Browse Source

Format control structures, classes, methods and function

To continue this formatting madness, here's a tiny patch that adds
unified formatting for control structures like if and loops as well as
classes, their methods and anonymous functions. This basically forces
the constructs to start on the same line. This is not exactly what PSR2
wants, but I think we can have a few exceptions with "our" style. The
starting of braces on the same line is pracrically standard for our
code.

This also removes and empty lines from method/function bodies at the
beginning and end.

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
tags/v19.0.0beta3
Christoph Wurst 4 years ago
parent
commit
caff1023ea
No account linked to committer's email address
100 changed files with 212 additions and 367 deletions
  1. 0
    1
      apps/accessibility/lib/AccessibilityProvider.php
  2. 0
    3
      apps/accessibility/lib/Controller/ConfigController.php
  3. 0
    1
      apps/accessibility/lib/Migration/RepairUserConfig.php
  4. 4
    4
      apps/admin_audit/lib/Actions/Action.php
  5. 16
    16
      apps/admin_audit/lib/Actions/Sharing.php
  6. 0
    2
      apps/admin_audit/lib/Actions/Trashbin.php
  7. 2
    2
      apps/admin_audit/lib/Actions/UserManagement.php
  8. 0
    2
      apps/admin_audit/lib/Actions/Versions.php
  9. 1
    4
      apps/admin_audit/lib/AppInfo/Application.php
  10. 2
    2
      apps/admin_audit/lib/BackgroundJobs/Rotate.php
  11. 0
    1
      apps/admin_audit/tests/Actions/SecurityTest.php
  12. 0
    1
      apps/cloud_federation_api/lib/AppInfo/Application.php
  13. 0
    1
      apps/cloud_federation_api/lib/Config.php
  14. 3
    7
      apps/cloud_federation_api/lib/Controller/RequestHandlerController.php
  15. 0
    1
      apps/comments/lib/AppInfo/Application.php
  16. 6
    6
      apps/comments/lib/Collaboration/CommentersSorter.php
  17. 1
    1
      apps/comments/lib/Controller/Notifications.php
  18. 3
    3
      apps/comments/lib/EventHandler.php
  19. 0
    1
      apps/comments/lib/Listener/LoadAdditionalScripts.php
  20. 0
    1
      apps/comments/lib/Listener/LoadSidebarScripts.php
  21. 8
    10
      apps/comments/lib/Notification/Listener.php
  22. 4
    4
      apps/comments/lib/Notification/Notifier.php
  23. 0
    2
      apps/comments/lib/Search/Result.php
  24. 1
    1
      apps/comments/tests/Unit/AppInfo/ApplicationTest.php
  25. 2
    2
      apps/comments/tests/Unit/Collaboration/CommentersSorterTest.php
  26. 0
    1
      apps/comments/tests/Unit/EventHandlerTest.php
  27. 0
    1
      apps/comments/tests/Unit/Notification/NotifierTest.php
  28. 0
    2
      apps/contactsinteraction/lib/AddressBook.php
  29. 0
    1
      apps/contactsinteraction/lib/AddressBookProvider.php
  30. 0
    2
      apps/contactsinteraction/lib/AppInfo/Application.php
  31. 0
    1
      apps/contactsinteraction/lib/BackgroundJob/CleanupJob.php
  32. 0
    2
      apps/contactsinteraction/lib/Card.php
  33. 0
    1
      apps/contactsinteraction/lib/Db/CardSearchDao.php
  34. 0
    1
      apps/contactsinteraction/lib/Db/RecentContact.php
  35. 0
    2
      apps/contactsinteraction/lib/Db/RecentContactMapper.php
  36. 0
    1
      apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php
  37. 0
    1
      apps/contactsinteraction/lib/Migration/Version010000Date20200304152605.php
  38. 1
    1
      apps/dav/appinfo/app.php
  39. 1
    1
      apps/dav/bin/chunkperf.php
  40. 1
    3
      apps/dav/lib/AppInfo/Application.php
  41. 0
    1
      apps/dav/lib/AppInfo/PluginManager.php
  42. 1
    3
      apps/dav/lib/Avatars/AvatarHome.php
  43. 0
    1
      apps/dav/lib/Avatars/AvatarNode.php
  44. 0
    1
      apps/dav/lib/Avatars/RootCollection.php
  45. 2
    2
      apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php
  46. 0
    1
      apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php
  47. 2
    2
      apps/dav/lib/BackgroundJob/RefreshWebcalJob.php
  48. 0
    1
      apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php
  49. 12
    12
      apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php
  50. 0
    1
      apps/dav/lib/BackgroundJob/UploadCleanup.php
  51. 1
    1
      apps/dav/lib/CalDAV/Activity/Backend.php
  52. 0
    4
      apps/dav/lib/CalDAV/Activity/Provider/Calendar.php
  53. 0
    1
      apps/dav/lib/CalDAV/Activity/Provider/Event.php
  54. 0
    1
      apps/dav/lib/CalDAV/Activity/Provider/Todo.php
  55. 4
    5
      apps/dav/lib/CalDAV/BirthdayService.php
  56. 2
    3
      apps/dav/lib/CalDAV/CachedSubscription.php
  57. 49
    75
      apps/dav/lib/CalDAV/CalDavBackend.php
  58. 0
    7
      apps/dav/lib/CalDAV/Calendar.php
  59. 1
    1
      apps/dav/lib/CalDAV/CalendarImpl.php
  60. 1
    1
      apps/dav/lib/CalDAV/CalendarManager.php
  61. 6
    6
      apps/dav/lib/CalDAV/CalendarObject.php
  62. 0
    1
      apps/dav/lib/CalDAV/CalendarRoot.php
  63. 0
    1
      apps/dav/lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php
  64. 0
    1
      apps/dav/lib/CalDAV/Integration/ExternalCalendar.php
  65. 0
    1
      apps/dav/lib/CalDAV/Integration/ICalendarProvider.php
  66. 0
    2
      apps/dav/lib/CalDAV/Plugin.php
  67. 0
    1
      apps/dav/lib/CalDAV/Principal/Collection.php
  68. 0
    1
      apps/dav/lib/CalDAV/Principal/User.php
  69. 0
    1
      apps/dav/lib/CalDAV/Proxy/ProxyMapper.php
  70. 0
    1
      apps/dav/lib/CalDAV/PublicCalendarRoot.php
  71. 1
    1
      apps/dav/lib/CalDAV/Reminder/NotificationProvider/AbstractProvider.php
  72. 4
    4
      apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php
  73. 0
    1
      apps/dav/lib/CalDAV/Reminder/NotificationProvider/ProviderNotAvailableException.php
  74. 1
    1
      apps/dav/lib/CalDAV/Reminder/NotificationProvider/PushProvider.php
  75. 0
    1
      apps/dav/lib/CalDAV/Reminder/NotificationTypeDoesNotExistException.php
  76. 1
    1
      apps/dav/lib/CalDAV/Reminder/Notifier.php
  77. 14
    15
      apps/dav/lib/CalDAV/Reminder/ReminderService.php
  78. 11
    12
      apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
  79. 2
    3
      apps/dav/lib/CalDAV/Schedule/IMipPlugin.php
  80. 0
    1
      apps/dav/lib/CalDAV/Search/SearchPlugin.php
  81. 0
    1
      apps/dav/lib/CalDAV/Search/Xml/Filter/ParamFilter.php
  82. 1
    1
      apps/dav/lib/CalDAV/WebcalCaching/Plugin.php
  83. 8
    8
      apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php
  84. 0
    1
      apps/dav/lib/Capabilities.php
  85. 0
    2
      apps/dav/lib/CardDAV/AddressBook.php
  86. 2
    7
      apps/dav/lib/CardDAV/AddressBookImpl.php
  87. 0
    3
      apps/dav/lib/CardDAV/AddressBookRoot.php
  88. 19
    30
      apps/dav/lib/CardDAV/CardDavBackend.php
  89. 0
    1
      apps/dav/lib/CardDAV/ContactsManager.php
  90. 0
    3
      apps/dav/lib/CardDAV/Converter.php
  91. 0
    3
      apps/dav/lib/CardDAV/HasPhotoPlugin.php
  92. 0
    1
      apps/dav/lib/CardDAV/ImageExportPlugin.php
  93. 0
    2
      apps/dav/lib/CardDAV/Integration/ExternalAddressBook.php
  94. 0
    1
      apps/dav/lib/CardDAV/Integration/IAddressBookProvider.php
  95. 0
    3
      apps/dav/lib/CardDAV/MultiGetExportPlugin.php
  96. 1
    2
      apps/dav/lib/CardDAV/PhotoCache.php
  97. 0
    3
      apps/dav/lib/CardDAV/Plugin.php
  98. 10
    13
      apps/dav/lib/CardDAV/SyncService.php
  99. 0
    2
      apps/dav/lib/CardDAV/UserAddressBooks.php
  100. 0
    0
      apps/dav/lib/Command/ListCalendars.php

+ 0
- 1
apps/accessibility/lib/AccessibilityProvider.php View File

] ]
]; ];
} }

} }

+ 0
- 3
apps/accessibility/lib/Controller/ConfigController.php View File

*/ */
public function setConfig(string $key, $value): DataResponse { public function setConfig(string $key, $value): DataResponse {
if ($key === 'theme' || $key === 'font' || $key === 'highcontrast') { if ($key === 'theme' || $key === 'font' || $key === 'highcontrast') {

if ($value === false || $value === '') { if ($value === false || $value === '') {
throw new OCSBadRequestException('Invalid value: ' . $value); throw new OCSBadRequestException('Invalid value: ' . $value);
} }
*/ */
public function deleteConfig(string $key): DataResponse { public function deleteConfig(string $key): DataResponse {
if ($key === 'theme' || $key === 'font' || $key === 'highcontrast') { if ($key === 'theme' || $key === 'font' || $key === 'highcontrast') {

$this->config->deleteUserValue($this->userId, $this->appName, $key); $this->config->deleteUserValue($this->userId, $this->appName, $key);
$userValues = $this->config->getUserKeys($this->userId, $this->appName); $userValues = $this->config->getUserKeys($this->userId, $this->appName);




throw new OCSBadRequestException('Invalid key: ' . $key); throw new OCSBadRequestException('Invalid key: ' . $key);
} }

} }

+ 0
- 1
apps/accessibility/lib/Migration/RepairUserConfig.php View File

}); });
$output->finishProgress(); $output->finishProgress();
} }

} }

+ 4
- 4
apps/admin_audit/lib/Actions/Action.php View File

array $params, array $params,
array $elements, array $elements,
bool $obfuscateParameters = false) { bool $obfuscateParameters = false) {
foreach($elements as $element) {
if(!isset($params[$element])) {
foreach ($elements as $element) {
if (!isset($params[$element])) {
if ($obfuscateParameters) { if ($obfuscateParameters) {
$this->logger->critical( $this->logger->critical(
'$params["'.$element.'"] was missing.', '$params["'.$element.'"] was missing.',
} }


$replaceArray = []; $replaceArray = [];
foreach($elements as $element) {
if($params[$element] instanceof \DateTime) {
foreach ($elements as $element) {
if ($params[$element] instanceof \DateTime) {
$params[$element] = $params[$element]->format('Y-m-d H:i:s'); $params[$element] = $params[$element]->format('Y-m-d H:i:s');
} }
$replaceArray[] = $params[$element]; $replaceArray[] = $params[$element];

+ 16
- 16
apps/admin_audit/lib/Actions/Sharing.php View File

* @param array $params * @param array $params
*/ */
public function shared(array $params) { public function shared(array $params) {
if($params['shareType'] === Share::SHARE_TYPE_LINK) {
if ($params['shareType'] === Share::SHARE_TYPE_LINK) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared via link with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared via link with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_USER) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_USER) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the user "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the user "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_GROUP) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_GROUP) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the group "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the group "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_ROOM) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_ROOM) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the room "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the room "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_EMAIL) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_EMAIL) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the email recipient "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the email recipient "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_CIRCLE) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_CIRCLE) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the circle "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the circle "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_REMOTE) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_REMOTE) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the remote user "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the remote user "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_REMOTE_GROUP) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_REMOTE_GROUP) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been shared to the remote group "%s" with permissions "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been shared to the remote group "%s" with permissions "%s" (Share ID: %s)',
$params, $params,
* @param array $params * @param array $params
*/ */
public function unshare(array $params) { public function unshare(array $params) {
if($params['shareType'] === Share::SHARE_TYPE_LINK) {
if ($params['shareType'] === Share::SHARE_TYPE_LINK) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_USER) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_USER) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the user "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the user "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_GROUP) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_GROUP) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the group "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the group "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_ROOM) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_ROOM) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the room "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the room "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_EMAIL) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_EMAIL) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the email recipient "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the email recipient "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_CIRCLE) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_CIRCLE) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the circle "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the circle "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_REMOTE) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_REMOTE) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the remote user "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the remote user "%s" (Share ID: %s)',
$params, $params,
'id', 'id',
] ]
); );
} elseif($params['shareType'] === Share::SHARE_TYPE_REMOTE_GROUP) {
} elseif ($params['shareType'] === Share::SHARE_TYPE_REMOTE_GROUP) {
$this->log( $this->log(
'The %s "%s" with ID "%s" has been unshared from the remote group "%s" (Share ID: %s)', 'The %s "%s" with ID "%s" has been unshared from the remote group "%s" (Share ID: %s)',
$params, $params,

+ 0
- 2
apps/admin_audit/lib/Actions/Trashbin.php View File

namespace OCA\AdminAudit\Actions; namespace OCA\AdminAudit\Actions;


class Trashbin extends Action { class Trashbin extends Action {

public function delete(array $params) { public function delete(array $params) {
$this->log('File "%s" deleted from trash bin.', $this->log('File "%s" deleted from trash bin.',
['path' => $params['path']], ['path'] ['path' => $params['path']], ['path']
['path' => $params['filePath']], ['path'] ['path' => $params['filePath']], ['path']
); );
} }

} }

+ 2
- 2
apps/admin_audit/lib/Actions/UserManagement.php View File

* @param array $params * @param array $params
*/ */
public function change(array $params) { public function change(array $params) {
switch($params['feature']) {
switch ($params['feature']) {
case 'enabled': case 'enabled':
$this->log( $this->log(
$params['value'] === true $params['value'] === true
* @param IUser $user * @param IUser $user
*/ */
public function setPassword(IUser $user) { public function setPassword(IUser $user) {
if($user->getBackendClassName() === 'Database') {
if ($user->getBackendClassName() === 'Database') {
$this->log( $this->log(
'Password of user "%s" has been changed', 'Password of user "%s" has been changed',
[ [

+ 0
- 2
apps/admin_audit/lib/Actions/Versions.php View File

namespace OCA\AdminAudit\Actions; namespace OCA\AdminAudit\Actions;


class Versions extends Action { class Versions extends Action {

public function rollback(array $params) { public function rollback(array $params) {
$this->log('Version "%s" of "%s" was restored.', $this->log('Version "%s" of "%s" was restored.',
[ [
['path'] ['path']
); );
} }

} }

+ 1
- 4
apps/admin_audit/lib/AppInfo/Application.php View File



$default = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log'; $default = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log';
$logFile = $config->getAppValue('admin_audit', 'logfile', $default); $logFile = $config->getAppValue('admin_audit', 'logfile', $default);
if($logFile === null) {
if ($logFile === null) {
$this->logger = $c->getLogger(); $this->logger = $c->getLogger();
return; return;
} }
$this->logger = $c->getLogFactory()->getCustomLogger($logFile); $this->logger = $c->getLogFactory()->getCustomLogger($logFile);

} }


public function register() { public function register() {
} }


protected function appHooks() { protected function appHooks() {

$eventDispatcher = $this->getContainer()->getServer()->getEventDispatcher(); $eventDispatcher = $this->getContainer()->getServer()->getEventDispatcher();
$eventDispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE, function (ManagerEvent $event) { $eventDispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE, function (ManagerEvent $event) {
$appActions = new AppManagement($this->logger); $appActions = new AppManagement($this->logger);
$appActions = new AppManagement($this->logger); $appActions = new AppManagement($this->logger);
$appActions->disableApp($event->getAppID()); $appActions->disableApp($event->getAppID());
}); });

} }


protected function consoleHooks() { protected function consoleHooks() {

+ 2
- 2
apps/admin_audit/lib/BackgroundJobs/Rotate.php View File

$default = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log'; $default = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log';
$this->filePath = $config->getAppValue('admin_audit', 'logfile', $default); $this->filePath = $config->getAppValue('admin_audit', 'logfile', $default);


if($this->filePath === '') {
if ($this->filePath === '') {
// default log file, nothing to do // default log file, nothing to do
return; return;
} }


$this->maxSize = $config->getSystemValue('log_rotate_size', 100 * 1024 * 1024); $this->maxSize = $config->getSystemValue('log_rotate_size', 100 * 1024 * 1024);


if($this->shouldRotateBySize()) {
if ($this->shouldRotateBySize()) {
$this->rotate(); $this->rotate();
} }
} }

+ 0
- 1
apps/admin_audit/tests/Actions/SecurityTest.php View File



$this->security->twofactorSuccess($this->user, ['provider' => 'myprovider']); $this->security->twofactorSuccess($this->user, ['provider' => 'myprovider']);
} }

} }

+ 0
- 1
apps/cloud_federation_api/lib/AppInfo/Application.php View File

use OCP\AppFramework\App; use OCP\AppFramework\App;


class Application extends App { class Application extends App {

public function __construct() { public function __construct() {
parent::__construct('cloud_federation_api'); parent::__construct('cloud_federation_api');



+ 0
- 1
apps/cloud_federation_api/lib/Config.php View File

return []; return [];
} }
} }

} }

+ 3
- 7
apps/cloud_federation_api/lib/Controller/RequestHandlerController.php View File

} }


if ($shareType === 'group') { if ($shareType === 'group') {
if(!$this->groupManager->groupExists($shareWith)) {
if (!$this->groupManager->groupExists($shareWith)) {
return new JSONResponse( return new JSONResponse(
['message' => 'Group "' . $shareWith . '" does not exists at ' . $this->urlGenerator->getBaseUrl()], ['message' => 'Group "' . $shareWith . '" does not exists at ' . $this->urlGenerator->getBaseUrl()],
Http::STATUS_BAD_REQUEST Http::STATUS_BAD_REQUEST


$user = $this->userManager->get($shareWith); $user = $this->userManager->get($shareWith);
$recipientDisplayName = ''; $recipientDisplayName = '';
if($user) {
if ($user) {
$recipientDisplayName = $user->getDisplayName(); $recipientDisplayName = $user->getDisplayName();
} }


return new JSONResponse( return new JSONResponse(
['recipientDisplayName' => $recipientDisplayName], ['recipientDisplayName' => $recipientDisplayName],
Http::STATUS_CREATED); Http::STATUS_CREATED);

} }


/** /**
return new JSONResponse($e->getReturnMessage(), Http::STATUS_BAD_REQUEST); return new JSONResponse($e->getReturnMessage(), Http::STATUS_BAD_REQUEST);
} catch (AuthenticationFailedException $e) { } catch (AuthenticationFailedException $e) {
return new JSONResponse(["message" => "RESOURCE_NOT_FOUND"], Http::STATUS_FORBIDDEN); return new JSONResponse(["message" => "RESOURCE_NOT_FOUND"], Http::STATUS_FORBIDDEN);
}
catch (\Exception $e) {
} catch (\Exception $e) {
return new JSONResponse( return new JSONResponse(
['message' => 'Internal error at ' . $this->urlGenerator->getBaseUrl()], ['message' => 'Internal error at ' . $this->urlGenerator->getBaseUrl()],
Http::STATUS_BAD_REQUEST Http::STATUS_BAD_REQUEST
} }


return new JSONResponse($result,Http::STATUS_CREATED); return new JSONResponse($result,Http::STATUS_CREATED);

} }


/** /**


return $uid; return $uid;
} }

} }

+ 0
- 1
apps/comments/lib/AppInfo/Application.php View File

use OCP\Util; use OCP\Util;


class Application extends App { class Application extends App {

const APP_ID = 'comments'; const APP_ID = 'comments';


public function __construct(array $urlParams = []) { public function __construct(array $urlParams = []) {

+ 6
- 6
apps/comments/lib/Collaboration/CommentersSorter.php View File

*/ */
public function sort(array &$sortArray, array $context) { public function sort(array &$sortArray, array $context) {
$commenters = $this->retrieveCommentsInformation($context['itemType'], $context['itemId']); $commenters = $this->retrieveCommentsInformation($context['itemType'], $context['itemId']);
if(count($commenters) === 0) {
if (count($commenters) === 0) {
return; return;
} }


foreach ($sortArray as $type => &$byType) { foreach ($sortArray as $type => &$byType) {
if(!isset($commenters[$type])) {
if (!isset($commenters[$type])) {
continue; continue;
} }




usort($workArray, function ($a, $b) use ($commenters, $type) { usort($workArray, function ($a, $b) use ($commenters, $type) {
$r = $this->compare($a[1], $b[1], $commenters[$type]); $r = $this->compare($a[1], $b[1], $commenters[$type]);
if($r === 0) {
if ($r === 0) {
$r = $a[0] - $b[0]; $r = $a[0] - $b[0];
} }
return $r; return $r;
*/ */
protected function retrieveCommentsInformation($type, $id) { protected function retrieveCommentsInformation($type, $id) {
$comments = $this->commentsManager->getForObject($type, $id); $comments = $this->commentsManager->getForObject($type, $id);
if(count($comments) === 0) {
if (count($comments) === 0) {
return []; return [];
} }


$actors = []; $actors = [];
foreach ($comments as $comment) { foreach ($comments as $comment) {
if(!isset($actors[$comment->getActorType()])) {
if (!isset($actors[$comment->getActorType()])) {
$actors[$comment->getActorType()] = []; $actors[$comment->getActorType()] = [];
} }
if(!isset($actors[$comment->getActorType()][$comment->getActorId()])) {
if (!isset($actors[$comment->getActorType()][$comment->getActorId()])) {
$actors[$comment->getActorType()][$comment->getActorId()] = 1; $actors[$comment->getActorType()][$comment->getActorId()] = 1;
} else { } else {
$actors[$comment->getActorType()][$comment->getActorId()]++; $actors[$comment->getActorType()][$comment->getActorId()]++;

+ 1
- 1
apps/comments/lib/Controller/Notifications.php View File



try { try {
$comment = $this->commentsManager->get($id); $comment = $this->commentsManager->get($id);
if($comment->getObjectType() !== 'files') {
if ($comment->getObjectType() !== 'files') {
return new NotFoundResponse(); return new NotFoundResponse();
} }
$userFolder = $this->rootFolder->getUserFolder($currentUser->getUID()); $userFolder = $this->rootFolder->getUserFolder($currentUser->getUID());

+ 3
- 3
apps/comments/lib/EventHandler.php View File

* @param CommentsEvent $event * @param CommentsEvent $event
*/ */
public function handle(CommentsEvent $event) { public function handle(CommentsEvent $event) {
if($event->getComment()->getObjectType() !== 'files') {
if ($event->getComment()->getObjectType() !== 'files') {
// this is a 'files'-specific Handler // this is a 'files'-specific Handler
return; return;
} }


$eventType = $event->getEvent(); $eventType = $event->getEvent();
if($eventType === CommentsEvent::EVENT_ADD
if ($eventType === CommentsEvent::EVENT_ADD
) { ) {
$this->notificationHandler($event); $this->notificationHandler($event);
$this->activityHandler($event); $this->activityHandler($event);
CommentsEvent::EVENT_UPDATE, CommentsEvent::EVENT_UPDATE,
CommentsEvent::EVENT_DELETE, CommentsEvent::EVENT_DELETE,
]; ];
if(in_array($eventType, $applicableEvents)) {
if (in_array($eventType, $applicableEvents)) {
$this->notificationHandler($event); $this->notificationHandler($event);
return; return;
} }

+ 0
- 1
apps/comments/lib/Listener/LoadAdditionalScripts.php View File

// we properly split it between files list and sidebar // we properly split it between files list and sidebar
Util::addScript(Application::APP_ID, 'comments'); Util::addScript(Application::APP_ID, 'comments');
} }

} }

+ 0
- 1
apps/comments/lib/Listener/LoadSidebarScripts.php View File

// we properly split it between files list and sidebar // we properly split it between files list and sidebar
Util::addScript(Application::APP_ID, 'comments'); Util::addScript(Application::APP_ID, 'comments');
} }

} }

+ 8
- 10
apps/comments/lib/Notification/Listener.php View File

IManager $notificationManager, IManager $notificationManager,
IUserManager $userManager IUserManager $userManager
) { ) {

$this->notificationManager = $notificationManager; $this->notificationManager = $notificationManager;
$this->userManager = $userManager; $this->userManager = $userManager;
} }
$comment = $event->getComment(); $comment = $event->getComment();


$mentions = $this->extractMentions($comment->getMentions()); $mentions = $this->extractMentions($comment->getMentions());
if(empty($mentions)) {
if (empty($mentions)) {
// no one to notify // no one to notify
return; return;
} }


$notification = $this->instantiateNotification($comment); $notification = $this->instantiateNotification($comment);


foreach($mentions as $uid) {
if(($comment->getActorType() === 'users' && $uid === $comment->getActorId())
foreach ($mentions as $uid) {
if (($comment->getActorType() === 'users' && $uid === $comment->getActorId())
|| !$this->userManager->userExists($uid) || !$this->userManager->userExists($uid)
) { ) {
// do not notify unknown users or yourself // do not notify unknown users or yourself
} }


$notification->setUser($uid); $notification->setUser($uid);
if($event->getEvent() === CommentsEvent::EVENT_DELETE
|| $event->getEvent() === CommentsEvent::EVENT_PRE_UPDATE)
{
if ($event->getEvent() === CommentsEvent::EVENT_DELETE
|| $event->getEvent() === CommentsEvent::EVENT_PRE_UPDATE) {
$this->notificationManager->markProcessed($notification); $this->notificationManager->markProcessed($notification);
} else { } else {
$this->notificationManager->notify($notification); $this->notificationManager->notify($notification);
* @return string[] containing the mentions, e.g. ['alice', 'bob'] * @return string[] containing the mentions, e.g. ['alice', 'bob']
*/ */
public function extractMentions(array $mentions) { public function extractMentions(array $mentions) {
if(empty($mentions)) {
if (empty($mentions)) {
return []; return [];
} }
$uids = []; $uids = [];
foreach($mentions as $mention) {
if($mention['type'] === 'user') {
foreach ($mentions as $mention) {
if ($mention['type'] === 'user') {
$uids[] = $mention['id']; $uids[] = $mention['id'];
} }
} }

+ 4
- 4
apps/comments/lib/Notification/Notifier.php View File

* @since 9.0.0 * @since 9.0.0
*/ */
public function prepare(INotification $notification, string $languageCode): INotification { public function prepare(INotification $notification, string $languageCode): INotification {
if($notification->getApp() !== 'comments') {
if ($notification->getApp() !== 'comments') {
throw new \InvalidArgumentException(); throw new \InvalidArgumentException();
} }
try { try {
$comment = $this->commentsManager->get($notification->getObjectId()); $comment = $this->commentsManager->get($notification->getObjectId());
} catch(NotFoundException $e) {
} catch (NotFoundException $e) {
// needs to be converted to InvalidArgumentException, otherwise none Notifications will be shown at all // needs to be converted to InvalidArgumentException, otherwise none Notifications will be shown at all
throw new \InvalidArgumentException('Comment not found', 0, $e); throw new \InvalidArgumentException('Comment not found', 0, $e);
} }
switch ($notification->getSubject()) { switch ($notification->getSubject()) {
case 'mention': case 'mention':
$parameters = $notification->getSubjectParameters(); $parameters = $notification->getSubjectParameters();
if($parameters[0] !== 'files') {
if ($parameters[0] !== 'files') {
throw new \InvalidArgumentException('Unsupported comment object'); throw new \InvalidArgumentException('Unsupported comment object');
} }
$userFolder = $this->rootFolder->getUserFolder($notification->getUser()); $userFolder = $this->rootFolder->getUserFolder($notification->getUser());
$nodes = $userFolder->getById((int)$parameters[1]); $nodes = $userFolder->getById((int)$parameters[1]);
if(empty($nodes)) {
if (empty($nodes)) {
throw new AlreadyProcessedException(); throw new AlreadyProcessedException();
} }
$node = $nodes[0]; $node = $nodes[0];

+ 0
- 2
apps/comments/lib/Search/Result.php View File

use OCP\Search\Result as BaseResult; use OCP\Search\Result as BaseResult;


class Result extends BaseResult { class Result extends BaseResult {

public $type = 'comment'; public $type = 'comment';
public $comment; public $comment;
public $authorId; public $authorId;


return $prefix . mb_substr($message, $start, $end - $start) . $suffix; return $prefix . mb_substr($message, $start, $end - $start) . $suffix;
} }

} }

+ 1
- 1
apps/comments/tests/Unit/AppInfo/ApplicationTest.php View File

Notifier::class, Notifier::class,
]; ];


foreach($services as $service) {
foreach ($services as $service) {
$s = $c->query($service); $s = $c->query($service);
$this->assertInstanceOf($service, $s); $this->assertInstanceOf($service, $s);
} }

+ 2
- 2
apps/comments/tests/Unit/Collaboration/CommentersSorterTest.php View File

*/ */
public function testSort($data) { public function testSort($data) {
$commentMocks = []; $commentMocks = [];
foreach($data['actors'] as $actorType => $actors) {
foreach ($data['actors'] as $actorType => $actors) {
foreach ($actors as $actorId => $noOfComments) { foreach ($actors as $actorId => $noOfComments) {
for($i=0;$i<$noOfComments;$i++) {
for ($i=0;$i<$noOfComments;$i++) {
$mock = $this->createMock(IComment::class); $mock = $this->createMock(IComment::class);
$mock->expects($this->atLeastOnce()) $mock->expects($this->atLeastOnce())
->method('getActorType') ->method('getActorType')

+ 0
- 1
apps/comments/tests/Unit/EventHandlerTest.php View File



$this->eventHandler->handle($event); $this->eventHandler->handle($event);
} }

} }

+ 0
- 1
apps/comments/tests/Unit/Notification/NotifierTest.php View File



$this->notifier->prepare($this->notification, $this->lc); $this->notifier->prepare($this->notification, $this->lc);
} }

} }

+ 0
- 2
apps/contactsinteraction/lib/AddressBook.php View File

use Sabre\DAVACL\IACL; use Sabre\DAVACL\IACL;


class AddressBook extends ExternalAddressBook implements IACL { class AddressBook extends ExternalAddressBook implements IACL {

public const URI = 'recent'; public const URI = 'recent';


use ACLTrait; use ACLTrait;
list(, $uid) = \Sabre\Uri\split($this->principalUri); list(, $uid) = \Sabre\Uri\split($this->principalUri);
return $uid; return $uid;
} }

} }

+ 0
- 1
apps/contactsinteraction/lib/AddressBookProvider.php View File



return null; return null;
} }

} }

+ 0
- 2
apps/contactsinteraction/lib/AppInfo/Application.php View File

use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventDispatcher;


class Application extends App { class Application extends App {

public const APP_ID = 'contactsinteraction'; public const APP_ID = 'contactsinteraction';


public function __construct() { public function __construct() {
private function registerListeners(IEventDispatcher $dispatcher): void { private function registerListeners(IEventDispatcher $dispatcher): void {
$dispatcher->addServiceListener(ContactInteractedWithEvent::class, ContactInteractionListener::class); $dispatcher->addServiceListener(ContactInteractedWithEvent::class, ContactInteractionListener::class);
} }

} }

+ 0
- 1
apps/contactsinteraction/lib/BackgroundJob/CleanupJob.php View File

$time->modify('-7days'); $time->modify('-7days');
$this->mapper->cleanUp($time->getTimestamp()); $this->mapper->cleanUp($time->getTimestamp());
} }

} }

+ 0
- 2
apps/contactsinteraction/lib/Card.php View File

use Sabre\DAVACL\IACL; use Sabre\DAVACL\IACL;


class Card implements ICard, IACL { class Card implements ICard, IACL {

use ACLTrait; use ACLTrait;


/** @var RecentContact */ /** @var RecentContact */
function getLastModified(): ?int { function getLastModified(): ?int {
return $this->contact->getLastContact(); return $this->contact->getLastContact();
} }

} }

+ 0
- 1
apps/contactsinteraction/lib/Db/CardSearchDao.php View File



return $card; return $card;
} }

} }

+ 0
- 1
apps/contactsinteraction/lib/Db/RecentContact.php View File

$this->addType('card', 'string'); $this->addType('card', 'string');
$this->addType('lastContact', 'int'); $this->addType('lastContact', 'int');
} }

} }

+ 0
- 2
apps/contactsinteraction/lib/Db/RecentContactMapper.php View File

use OCP\IUser; use OCP\IUser;


class RecentContactMapper extends QBMapper { class RecentContactMapper extends QBMapper {

public const TABLE_NAME = 'recent_contact'; public const TABLE_NAME = 'recent_contact';


public function __construct(IDBConnection $db) { public function __construct(IDBConnection $db) {


$delete->execute(); $delete->execute();
} }

} }

+ 0
- 1
apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php View File



return (new VCard($props))->serialize(); return (new VCard($props))->serialize();
} }

} }

+ 0
- 1
apps/contactsinteraction/lib/Migration/Version010000Date20200304152605.php View File



return $schema; return $schema;
} }

} }

+ 1
- 1
apps/dav/appinfo/app.php View File

$job = $app->getContainer()->query(\OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob::class); $job = $app->getContainer()->query(\OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob::class);
$job->run([]); $job->run([]);
$app->getContainer()->getServer()->getJobList()->setLastRun($job); $app->getContainer()->getServer()->getJobList()->setLastRun($job);
} catch(\Exception $ex) {
} catch (\Exception $ex) {
$app->getContainer()->getServer()->getLogger()->logException($ex); $app->getContainer()->getServer()->getLogger()->logException($ex);
} }
}; };

+ 1
- 1
apps/dav/bin/chunkperf.php View File

$stream = fopen($file, 'r'); $stream = fopen($file, 'r');


$index = 0; $index = 0;
while(!feof($stream)) {
while (!feof($stream)) {
request($client, 'PUT', "$uploadUrl/$index", fread($stream, $chunkSize)); request($client, 'PUT', "$uploadUrl/$index", fread($stream, $chunkSize));
$index++; $index++;
} }

+ 1
- 3
apps/dav/lib/AppInfo/Application.php View File

use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Component\EventDispatcher\GenericEvent;


class Application extends App { class Application extends App {

const APP_ID = 'dav'; const APP_ID = 'dav';


/** /**
$notificationProviderManager->registerProvider(AudioProvider::class); $notificationProviderManager->registerProvider(AudioProvider::class);
$notificationProviderManager->registerProvider(EmailProvider::class); $notificationProviderManager->registerProvider(EmailProvider::class);
$notificationProviderManager->registerProvider(PushProvider::class); $notificationProviderManager->registerProvider(PushProvider::class);
} catch(\Exception $ex) {
} catch (\Exception $ex) {
$this->getContainer()->getServer()->getLogger()->logException($ex); $this->getContainer()->getServer()->getLogger()->logException($ex);
} }
} }

} }

+ 0
- 1
apps/dav/lib/AppInfo/PluginManager.php View File

$this->calendarPlugins[] = $instantiatedCalendarPlugin; $this->calendarPlugins[] = $instantiatedCalendarPlugin;
} }
} }

} }

+ 1
- 3
apps/dav/lib/Avatars/AvatarHome.php View File

return [ return [
$this->getChild('96.jpeg') $this->getChild('96.jpeg')
]; ];
} catch(NotFound $exception) {
} catch (NotFound $exception) {
return []; return [];
} }
} }
public function getLastModified() { public function getLastModified() {
return null; return null;
} }


} }

+ 0
- 1
apps/dav/lib/Avatars/AvatarNode.php View File

return (int)$timestamp; return (int)$timestamp;
} }
return $timestamp; return $timestamp;

} }
} }

+ 0
- 1
apps/dav/lib/Avatars/RootCollection.php View File

public function getName() { public function getName() {
return 'avatars'; return 'avatars';
} }

} }

+ 2
- 2
apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php View File

->orderBy('id', 'ASC'); ->orderBy('id', 'ASC');


$stmt = $query->execute(); $stmt = $query->execute();
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$offset = $row['id']; $offset = $row['id'];
if (is_resource($row['calendardata'])) { if (is_resource($row['calendardata'])) {
$row['calendardata'] = stream_get_contents($row['calendardata']); $row['calendardata'] = stream_get_contents($row['calendardata']);


try { try {
$this->reminderService->onTouchCalendarObject('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $row); $this->reminderService->onTouchCalendarObject('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $row);
} catch(\Exception $ex) {
} catch (\Exception $ex) {
$this->logger->logException($ex); $this->logger->logException($ex);
} }



+ 0
- 1
apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php View File

// Delete all shares expired 24 hours ago // Delete all shares expired 24 hours ago
$this->mapper->deleteExpired($this->timeFactory->getTime() - 60*60*24); $this->mapper->deleteExpired($this->timeFactory->getTime() - 60*60*24);
} }

} }

+ 2
- 2
apps/dav/lib/BackgroundJob/RefreshWebcalJob.php View File

try { try {
/** @var DateInterval $dateInterval */ /** @var DateInterval $dateInterval */
$dateInterval = DateTimeParser::parseDuration($refreshRate); $dateInterval = DateTimeParser::parseDuration($refreshRate);
} catch(InvalidDataException $ex) {
} catch (InvalidDataException $ex) {
$this->logger->logException($ex); $this->logger->logException($ex);
$this->logger->warning("Subscription $subscriptionId could not be refreshed, refreshrate in database is invalid"); $this->logger->warning("Subscription $subscriptionId could not be refreshed, refreshrate in database is invalid");
return; return;
RefreshWebcalService::STRIP_TODOS, RefreshWebcalService::STRIP_TODOS,
]; ];


foreach($forceInt as $column) {
foreach ($forceInt as $column) {
if (isset($row[$column])) { if (isset($row[$column])) {
$row[$column] = (int) $row[$column]; $row[$column] = (int) $row[$column];
} }

+ 0
- 1
apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php View File

]); ]);
}); });
} }

} }

+ 12
- 12
apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php View File

string $principalPrefix):void { string $principalPrefix):void {
$backends = $backendManager->getBackends(); $backends = $backendManager->getBackends();


foreach($backends as $backend) {
foreach ($backends as $backend) {
$backendId = $backend->getBackendIdentifier(); $backendId = $backend->getBackendIdentifier();


try { try {
} else { } else {
$list = $backend->listAllRooms(); $list = $backend->listAllRooms();
} }
} catch(BackendTemporarilyUnavailableException $ex) {
} catch (BackendTemporarilyUnavailableException $ex) {
continue; continue;
} }


$deletedIds = array_diff($cachedList, $list); $deletedIds = array_diff($cachedList, $list);
$editedIds = array_intersect($list, $cachedList); $editedIds = array_intersect($list, $cachedList);


foreach($newIds as $newId) {
foreach ($newIds as $newId) {
try { try {
if ($backend instanceof IResourceBackend) { if ($backend instanceof IResourceBackend) {
$resource = $backend->getResource($newId); $resource = $backend->getResource($newId);
if ($resource instanceof IMetadataProvider) { if ($resource instanceof IMetadataProvider) {
$metadata = $this->getAllMetadataOfBackend($resource); $metadata = $this->getAllMetadataOfBackend($resource);
} }
} catch(BackendTemporarilyUnavailableException $ex) {
} catch (BackendTemporarilyUnavailableException $ex) {
continue; continue;
} }


// when an event is actually scheduled with this resource / room // when an event is actually scheduled with this resource / room
} }


foreach($deletedIds as $deletedId) {
foreach ($deletedIds as $deletedId) {
$id = $this->getIdForBackendAndResource($dbTable, $backendId, $deletedId); $id = $this->getIdForBackendAndResource($dbTable, $backendId, $deletedId);
$this->deleteFromCache($dbTable, $id); $this->deleteFromCache($dbTable, $id);
$this->deleteMetadataFromCache($dbTableMetadata, $foreignKey, $id); $this->deleteMetadataFromCache($dbTableMetadata, $foreignKey, $id);
$this->deleteCalendarDataForResource($principalPrefix, $principalName); $this->deleteCalendarDataForResource($principalPrefix, $principalName);
} }


foreach($editedIds as $editedId) {
foreach ($editedIds as $editedId) {
$id = $this->getIdForBackendAndResource($dbTable, $backendId, $editedId); $id = $this->getIdForBackendAndResource($dbTable, $backendId, $editedId);


try { try {
if ($resource instanceof IMetadataProvider) { if ($resource instanceof IMetadataProvider) {
$metadata = $this->getAllMetadataOfBackend($resource); $metadata = $this->getAllMetadataOfBackend($resource);
} }
} catch(BackendTemporarilyUnavailableException $ex) {
} catch (BackendTemporarilyUnavailableException $ex) {
continue; continue;
} }


string $foreignKey, string $foreignKey,
int $foreignId, int $foreignId,
array $metadata):void { array $metadata):void {
foreach($metadata as $key => $value) {
foreach ($metadata as $key => $value) {
$query = $this->dbConnection->getQueryBuilder(); $query = $this->dbConnection->getQueryBuilder();
$query->insert($table) $query->insert($table)
->values([ ->values([
->execute(); ->execute();
} }


foreach($deletedMetadata as $key => $value) {
foreach ($deletedMetadata as $key => $value) {
$query = $this->dbConnection->getQueryBuilder(); $query = $this->dbConnection->getQueryBuilder();
$query->delete($dbTable) $query->delete($dbTable)
->where($query->expr()->eq($foreignKey, $query->createNamedParameter($id))) ->where($query->expr()->eq($foreignKey, $query->createNamedParameter($id)))
} }


$existingKeys = array_keys(array_intersect_key($metadata, $cachedMetadata)); $existingKeys = array_keys(array_intersect_key($metadata, $cachedMetadata));
foreach($existingKeys as $existingKey) {
foreach ($existingKeys as $existingKey) {
if ($metadata[$existingKey] !== $cachedMetadata[$existingKey]) { if ($metadata[$existingKey] !== $cachedMetadata[$existingKey]) {
$query = $this->dbConnection->getQueryBuilder(); $query = $this->dbConnection->getQueryBuilder();
$query->update($dbTable) $query->update($dbTable)


$keys = $resource->getAllAvailableMetadataKeys(); $keys = $resource->getAllAvailableMetadataKeys();
$metadata = []; $metadata = [];
foreach($keys as $key) {
foreach ($keys as $key) {
$metadata[$key] = $resource->getMetadataForKey($key); $metadata[$key] = $resource->getMetadataForKey($key);
} }


$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC); $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);


$metadata = []; $metadata = [];
foreach($rows as $row) {
foreach ($rows as $row) {
$metadata[$row['key']] = $row['value']; $metadata[$row['key']] = $row['value'];
} }



+ 0
- 1
apps/dav/lib/BackgroundJob/UploadCleanup.php View File

$this->jobList->remove(self::class, $argument); $this->jobList->remove(self::class, $argument);
} }
} }

} }

+ 1
- 1
apps/dav/lib/CalDAV/Activity/Backend.php View File

protected function getObjectNameAndType(array $objectData) { protected function getObjectNameAndType(array $objectData) {
$vObject = Reader::read($objectData['calendardata']); $vObject = Reader::read($objectData['calendardata']);
$component = $componentType = null; $component = $componentType = null;
foreach($vObject->getComponents() as $component) {
foreach ($vObject->getComponents() as $component) {
if (in_array($component->name, ['VEVENT', 'VTODO'])) { if (in_array($component->name, ['VEVENT', 'VTODO'])) {
$componentType = $component->name; $componentType = $component->name;
break; break;

+ 0
- 4
apps/dav/lib/CalDAV/Activity/Provider/Calendar.php View File

use OCP\L10N\IFactory; use OCP\L10N\IFactory;


class Calendar extends Base { class Calendar extends Base {

const SUBJECT_ADD = 'calendar_add'; const SUBJECT_ADD = 'calendar_add';
const SUBJECT_UPDATE = 'calendar_update'; const SUBJECT_UPDATE = 'calendar_update';
const SUBJECT_DELETE = 'calendar_delete'; const SUBJECT_DELETE = 'calendar_delete';
$subject = $this->l->t('{actor} updated calendar {calendar}'); $subject = $this->l->t('{actor} updated calendar {calendar}');
} elseif ($event->getSubject() === self::SUBJECT_UPDATE . '_self') { } elseif ($event->getSubject() === self::SUBJECT_UPDATE . '_self') {
$subject = $this->l->t('You updated calendar {calendar}'); $subject = $this->l->t('You updated calendar {calendar}');

} elseif ($event->getSubject() === self::SUBJECT_PUBLISH . '_self') { } elseif ($event->getSubject() === self::SUBJECT_PUBLISH . '_self') {
$subject = $this->l->t('You shared calendar {calendar} as public link'); $subject = $this->l->t('You shared calendar {calendar} as public link');
} elseif ($event->getSubject() === self::SUBJECT_UNPUBLISH . '_self') { } elseif ($event->getSubject() === self::SUBJECT_UNPUBLISH . '_self') {
$subject = $this->l->t('You removed public link for calendar {calendar}'); $subject = $this->l->t('You removed public link for calendar {calendar}');

} elseif ($event->getSubject() === self::SUBJECT_SHARE_USER) { } elseif ($event->getSubject() === self::SUBJECT_SHARE_USER) {
$subject = $this->l->t('{actor} shared calendar {calendar} with you'); $subject = $this->l->t('{actor} shared calendar {calendar} with you');
} elseif ($event->getSubject() === self::SUBJECT_SHARE_USER . '_you') { } elseif ($event->getSubject() === self::SUBJECT_SHARE_USER . '_you') {
$subject = $this->l->t('{actor} unshared calendar {calendar} from {user}'); $subject = $this->l->t('{actor} unshared calendar {calendar} from {user}');
} elseif ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_self') { } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_self') {
$subject = $this->l->t('{actor} unshared calendar {calendar} from themselves'); $subject = $this->l->t('{actor} unshared calendar {calendar} from themselves');

} elseif ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_you') { } elseif ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_you') {
$subject = $this->l->t('You shared calendar {calendar} with group {group}'); $subject = $this->l->t('You shared calendar {calendar} with group {group}');
} elseif ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_by') { } elseif ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_by') {

+ 0
- 1
apps/dav/lib/CalDAV/Activity/Provider/Event.php View File

use OCP\L10N\IFactory; use OCP\L10N\IFactory;


class Event extends Base { class Event extends Base {

const SUBJECT_OBJECT_ADD = 'object_add'; const SUBJECT_OBJECT_ADD = 'object_add';
const SUBJECT_OBJECT_UPDATE = 'object_update'; const SUBJECT_OBJECT_UPDATE = 'object_update';
const SUBJECT_OBJECT_DELETE = 'object_delete'; const SUBJECT_OBJECT_DELETE = 'object_delete';

+ 0
- 1
apps/dav/lib/CalDAV/Activity/Provider/Todo.php View File

$subject = $this->l->t('{actor} updated todo {todo} in list {calendar}'); $subject = $this->l->t('{actor} updated todo {todo} in list {calendar}');
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_self') { } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_self') {
$subject = $this->l->t('You updated todo {todo} in list {calendar}'); $subject = $this->l->t('You updated todo {todo} in list {calendar}');

} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed') { } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed') {
$subject = $this->l->t('{actor} solved todo {todo} in list {calendar}'); $subject = $this->l->t('{actor} solved todo {todo} in list {calendar}');
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self') { } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self') {

+ 4
- 5
apps/dav/lib/CalDAV/BirthdayService.php View File

* @package OCA\DAV\CalDAV * @package OCA\DAV\CalDAV
*/ */
class BirthdayService { class BirthdayService {

const BIRTHDAY_CALENDAR_URI = 'contact_birthdays'; const BIRTHDAY_CALENDAR_URI = 'contact_birthdays';


/** @var GroupPrincipalBackend */ /** @var GroupPrincipalBackend */
$calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); $calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
$calendarObjects = $this->calDavBackEnd->getCalendarObjects($calendar['id'], CalDavBackend::CALENDAR_TYPE_CALENDAR); $calendarObjects = $this->calDavBackEnd->getCalendarObjects($calendar['id'], CalDavBackend::CALENDAR_TYPE_CALENDAR);


foreach($calendarObjects as $calendarObject) {
foreach ($calendarObjects as $calendarObject) {
$this->calDavBackEnd->deleteCalendarObject($calendar['id'], $calendarObject['uri'], CalDavBackend::CALENDAR_TYPE_CALENDAR); $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $calendarObject['uri'], CalDavBackend::CALENDAR_TYPE_CALENDAR);
} }
} }
$principal = 'principals/users/'.$user; $principal = 'principals/users/'.$user;
$this->ensureCalendarExists($principal); $this->ensureCalendarExists($principal);
$books = $this->cardDavBackEnd->getAddressBooksForUser($principal); $books = $this->cardDavBackEnd->getAddressBooksForUser($principal);
foreach($books as $book) {
foreach ($books as $book) {
$cards = $this->cardDavBackEnd->getCards($book['id']); $cards = $this->cardDavBackEnd->getCards($book['id']);
foreach($cards as $card) {
foreach ($cards as $card) {
$this->onCardChanged((int) $book['id'], $card['uri'], $card['carddata']); $this->onCardChanged((int) $book['id'], $card['uri'], $card['carddata']);
} }
} }
return ''; return '';
} }
} else { } else {
switch($field) {
switch ($field) {
case 'BDAY': case 'BDAY':
return implode('', [ return implode('', [
$name, $name,

+ 2
- 3
apps/dav/lib/CalDAV/CachedSubscription.php View File



$obj['acl'] = $this->getChildACL(); $obj['acl'] = $this->getChildACL();
return new CachedSubscriptionObject($this->caldavBackend, $this->calendarInfo, $obj); return new CachedSubscriptionObject($this->caldavBackend, $this->calendarInfo, $obj);

} }


/** /**
$objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id'], CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION); $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id'], CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION);


$children = []; $children = [];
foreach($objs as $obj) {
foreach ($objs as $obj) {
$children[] = new CachedSubscriptionObject($this->caldavBackend, $this->calendarInfo, $obj); $children[] = new CachedSubscriptionObject($this->caldavBackend, $this->calendarInfo, $obj);
} }


$objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths, CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION); $objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths, CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION);


$children = []; $children = [];
foreach($objs as $obj) {
foreach ($objs as $obj) {
$children[] = new CachedSubscriptionObject($this->caldavBackend, $this->calendarInfo, $obj); $children[] = new CachedSubscriptionObject($this->caldavBackend, $this->calendarInfo, $obj);
} }



+ 49
- 75
apps/dav/lib/CalDAV/CalDavBackend.php View File

* @package OCA\DAV\CalDAV * @package OCA\DAV\CalDAV
*/ */
class CalDavBackend extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport { class CalDavBackend extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport {

const CALENDAR_TYPE_CALENDAR = 0; const CALENDAR_TYPE_CALENDAR = 0;
const CALENDAR_TYPE_SUBSCRIPTION = 1; const CALENDAR_TYPE_SUBSCRIPTION = 1;


$stmt = $query->execute(); $stmt = $query->execute();


$calendars = []; $calendars = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {

while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$components = []; $components = [];
if ($row['components']) { if ($row['components']) {
$components = explode(',',$row['components']); $components = explode(',',$row['components']);
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint), '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
]; ];


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


->execute(); ->execute();


$readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only'; $readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only';
while($row = $result->fetch()) {
while ($row = $result->fetch()) {
if ($row['principaluri'] === $principalUri) { if ($row['principaluri'] === $principalUri) {
continue; continue;
} }
$readOnlyPropertyName => $readOnly, $readOnlyPropertyName => $readOnly,
]; ];


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


->orderBy('calendarorder', 'ASC'); ->orderBy('calendarorder', 'ASC');
$stmt = $query->execute(); $stmt = $query->execute();
$calendars = []; $calendars = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$components = []; $components = [];
if ($row['components']) { if ($row['components']) {
$components = explode(',',$row['components']); $components = explode(',',$row['components']);
'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
]; ];
foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar'))) ->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar')))
->execute(); ->execute();


while($row = $result->fetch()) {
while ($row = $result->fetch()) {
list(, $name) = Uri\split($row['principaluri']); list(, $name) = Uri\split($row['principaluri']);
$row['displayname'] = $row['displayname'] . "($name)"; $row['displayname'] = $row['displayname'] . "($name)";
$components = []; $components = [];
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
]; ];


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
]; ];


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


$this->addOwnerPrincipal($calendar); $this->addOwnerPrincipal($calendar);


return $calendar; return $calendar;

} }


/** /**
'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
]; ];


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
]; ];


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName]; $calendar[$xmlName] = $row[$dbName];
} }


'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
]; ];


foreach($this->subscriptionPropertyMap as $xmlName=>$dbName) {
foreach ($this->subscriptionPropertyMap as $xmlName=>$dbName) {
if (!is_null($row[$dbName])) { if (!is_null($row[$dbName])) {
$subscription[$xmlName] = $row[$dbName]; $subscription[$xmlName] = $row[$dbName];
} }
$values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent'); $values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent');
} }


foreach($this->propertyMap as $xmlName=>$dbName) {
foreach ($this->propertyMap as $xmlName=>$dbName) {
if (isset($properties[$xmlName])) { if (isset($properties[$xmlName])) {
$values[$dbName] = $properties[$xmlName]; $values[$dbName] = $properties[$xmlName];
} }


$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$query->insert('calendars'); $query->insert('calendars');
foreach($values as $column => $value) {
foreach ($values as $column => $value) {
$query->setValue($column, $query->createNamedParameter($value)); $query->setValue($column, $query->createNamedParameter($value));
} }
$query->execute(); $query->execute();
$propPatch->handle($supportedProperties, function ($mutations) use ($calendarId) { $propPatch->handle($supportedProperties, function ($mutations) use ($calendarId) {
$newValues = []; $newValues = [];
foreach ($mutations as $propertyName => $propertyValue) { foreach ($mutations as $propertyName => $propertyValue) {

switch ($propertyName) { switch ($propertyName) {
case '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp': case '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp':
$fieldName = 'transparent'; $fieldName = 'transparent';
$newValues[$fieldName] = $propertyValue; $newValues[$fieldName] = $propertyValue;
break; break;
} }

} }
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$query->update('calendars'); $query->update('calendars');
$stmt = $query->execute(); $stmt = $query->execute();


$result = []; $result = [];
foreach($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$result[] = [ $result[] = [
'id' => $row['id'], 'id' => $row['id'],
'uri' => $row['uri'], 'uri' => $row['uri'],
$stmt = $query->execute(); $stmt = $query->execute();
$row = $stmt->fetch(\PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);


if(!$row) {
if (!$row) {
return null; return null;
} }


$requirePostFilter = false; $requirePostFilter = false;
} }
} }

} }
$columns = ['uri']; $columns = ['uri'];
if ($requirePostFilter) { if ($requirePostFilter) {
$stmt = $query->execute(); $stmt = $query->execute();


$result = []; $result = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($requirePostFilter) { if ($requirePostFilter) {
// validateFilterForObject will parse the calendar data // validateFilterForObject will parse the calendar data
// catch parsing errors // catch parsing errors
try { try {
$matches = $this->validateFilterForObject($row, $filters); $matches = $this->validateFilterForObject($row, $filters);
} catch(ParseException $ex) {
} catch (ParseException $ex) {
$this->logger->logException($ex, [ $this->logger->logException($ex, [
'app' => 'dav', 'app' => 'dav',
'message' => 'Caught parsing exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$id.' uri:'.$row['uri'] 'message' => 'Caught parsing exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$id.' uri:'.$row['uri']


$uriMapper = []; $uriMapper = [];


foreach($calendars as $calendar) {
foreach ($calendars as $calendar) {
if ($calendar['{http://owncloud.org/ns}owner-principal'] === $principalUri) { if ($calendar['{http://owncloud.org/ns}owner-principal'] === $principalUri) {
$ownCalendars[] = $calendar['id']; $ownCalendars[] = $calendar['id'];
} else { } else {
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
// Calendar id expressions // Calendar id expressions
$calendarExpressions = []; $calendarExpressions = [];
foreach($ownCalendars as $id) {
foreach ($ownCalendars as $id) {
$calendarExpressions[] = $query->expr()->andX( $calendarExpressions[] = $query->expr()->andX(
$query->expr()->eq('c.calendarid', $query->expr()->eq('c.calendarid',
$query->createNamedParameter($id)), $query->createNamedParameter($id)),
$query->expr()->eq('c.calendartype', $query->expr()->eq('c.calendartype',
$query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR))); $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
} }
foreach($sharedCalendars as $id) {
foreach ($sharedCalendars as $id) {
$calendarExpressions[] = $query->expr()->andX( $calendarExpressions[] = $query->expr()->andX(
$query->expr()->eq('c.calendarid', $query->expr()->eq('c.calendarid',
$query->createNamedParameter($id)), $query->createNamedParameter($id)),


// Component expressions // Component expressions
$compExpressions = []; $compExpressions = [];
foreach($filters['comps'] as $comp) {
foreach ($filters['comps'] as $comp) {
$compExpressions[] = $query->expr() $compExpressions[] = $query->expr()
->eq('c.componenttype', $query->createNamedParameter($comp)); ->eq('c.componenttype', $query->createNamedParameter($comp));
} }
} }


$propParamExpressions = []; $propParamExpressions = [];
foreach($filters['props'] as $prop) {
foreach ($filters['props'] as $prop) {
$propParamExpressions[] = $query->expr()->andX( $propParamExpressions[] = $query->expr()->andX(
$query->expr()->eq('i.name', $query->createNamedParameter($prop)), $query->expr()->eq('i.name', $query->createNamedParameter($prop)),
$query->expr()->isNull('i.parameter') $query->expr()->isNull('i.parameter')
); );
} }
foreach($filters['params'] as $param) {
foreach ($filters['params'] as $param) {
$propParamExpressions[] = $query->expr()->andX( $propParamExpressions[] = $query->expr()->andX(
$query->expr()->eq('i.name', $query->createNamedParameter($param['property'])), $query->expr()->eq('i.name', $query->createNamedParameter($param['property'])),
$query->expr()->eq('i.parameter', $query->createNamedParameter($param['parameter'])) $query->expr()->eq('i.parameter', $query->createNamedParameter($param['parameter']))
$stmt = $query->execute(); $stmt = $query->execute();


$result = []; $result = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$path = $uriMapper[$row['calendarid']] . '/' . $row['uri']; $path = $uriMapper[$row['calendarid']] . '/' . $row['uri'];
if (!in_array($path, $result)) { if (!in_array($path, $result)) {
$result[] = $path; $result[] = $path;
} }


$or = $innerQuery->expr()->orX(); $or = $innerQuery->expr()->orX();
foreach($searchProperties as $searchProperty) {
foreach ($searchProperties as $searchProperty) {
$or->add($innerQuery->expr()->eq('op.name', $or->add($innerQuery->expr()->eq('op.name',
$outerQuery->createNamedParameter($searchProperty))); $outerQuery->createNamedParameter($searchProperty)));
} }
if (isset($options['timerange']['start']) && $options['timerange']['start'] instanceof DateTime) { if (isset($options['timerange']['start']) && $options['timerange']['start'] instanceof DateTime) {
$outerQuery->andWhere($outerQuery->expr()->gt('lastoccurence', $outerQuery->andWhere($outerQuery->expr()->gt('lastoccurence',
$outerQuery->createNamedParameter($options['timerange']['start']->getTimeStamp()))); $outerQuery->createNamedParameter($options['timerange']['start']->getTimeStamp())));

} }
if (isset($options['timerange']['end']) && $options['timerange']['end'] instanceof DateTime) { if (isset($options['timerange']['end']) && $options['timerange']['end'] instanceof DateTime) {
$outerQuery->andWhere($outerQuery->expr()->lt('firstoccurence', $outerQuery->andWhere($outerQuery->expr()->lt('firstoccurence',


if (isset($options['types'])) { if (isset($options['types'])) {
$or = $outerQuery->expr()->orX(); $or = $outerQuery->expr()->orX();
foreach($options['types'] as $type) {
foreach ($options['types'] as $type) {
$or->add($outerQuery->expr()->eq('componenttype', $or->add($outerQuery->expr()->eq('componenttype',
$outerQuery->createNamedParameter($type))); $outerQuery->createNamedParameter($type)));
} }
$comps = $calendarData->getComponents(); $comps = $calendarData->getComponents();
$objects = []; $objects = [];
$timezones = []; $timezones = [];
foreach($comps as $comp) {
foreach ($comps as $comp) {
if ($comp instanceof VTimeZone) { if ($comp instanceof VTimeZone) {
$timezones[] = $comp; $timezones[] = $comp;
} else { } else {
}); });
$validationRules = $comp->getValidationRules(); $validationRules = $comp->getValidationRules();


foreach($subComponents as $subComponent) {
foreach ($subComponents as $subComponent) {
$name = $subComponent->name; $name = $subComponent->name;
if (!isset($data[$name])) { if (!isset($data[$name])) {
$data[$name] = []; $data[$name] = [];
$data[$name][] = $this->transformSearchData($subComponent); $data[$name][] = $this->transformSearchData($subComponent);
} }


foreach($properties as $property) {
foreach ($properties as $property) {
$name = $property->name; $name = $property->name;
if (!isset($validationRules[$name])) { if (!isset($validationRules[$name])) {
$validationRules[$name] = '*'; $validationRules[$name] = '*';
* @return string|null * @return string|null
*/ */
function getCalendarObjectByUID($principalUri, $uid) { function getCalendarObjectByUID($principalUri, $uid) {

$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$query->selectAlias('c.uri', 'calendaruri')->selectAlias('co.uri', 'objecturi') $query->selectAlias('c.uri', 'calendaruri')->selectAlias('co.uri', 'objecturi')
->from('calendarobjects', 'co') ->from('calendarobjects', 'co')
]; ];


if ($syncToken) { if ($syncToken) {

$query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`"; $query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`";
if ($limit>0) { if ($limit>0) {
$query.= " LIMIT " . (int)$limit; $query.= " LIMIT " . (int)$limit;


// This loop ensures that any duplicates are overwritten, only the // This loop ensures that any duplicates are overwritten, only the
// last change on a node is relevant. // last change on a node is relevant.
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {

while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$changes[$row['uri']] = $row['operation']; $changes[$row['uri']] = $row['operation'];

} }


foreach($changes as $uri => $operation) {

switch($operation) {
foreach ($changes as $uri => $operation) {
switch ($operation) {
case 1: case 1:
$result['added'][] = $uri; $result['added'][] = $uri;
break; break;
$result['deleted'][] = $uri; $result['deleted'][] = $uri;
break; break;
} }

} }
} else { } else {
// No synctoken supplied, this is the initial sync. // No synctoken supplied, this is the initial sync.
$result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN); $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
} }
return $result; return $result;

} }


/** /**
$stmt =$query->execute(); $stmt =$query->execute();


$subscriptions = []; $subscriptions = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {

while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$subscription = [ $subscription = [
'id' => $row['id'], 'id' => $row['id'],
'uri' => $row['uri'], 'uri' => $row['uri'],
'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
]; ];


foreach($this->subscriptionPropertyMap as $xmlName=>$dbName) {
foreach ($this->subscriptionPropertyMap as $xmlName=>$dbName) {
if (!is_null($row[$dbName])) { if (!is_null($row[$dbName])) {
$subscription[$xmlName] = $row[$dbName]; $subscription[$xmlName] = $row[$dbName];
} }
} }


$subscriptions[] = $subscription; $subscriptions[] = $subscription;

} }


return $subscriptions; return $subscriptions;
* @return mixed * @return mixed
*/ */
function createSubscription($principalUri, $uri, array $properties) { function createSubscription($principalUri, $uri, array $properties) {

if (!isset($properties['{http://calendarserver.org/ns/}source'])) { if (!isset($properties['{http://calendarserver.org/ns/}source'])) {
throw new Forbidden('The {http://calendarserver.org/ns/}source property is required when creating subscriptions'); throw new Forbidden('The {http://calendarserver.org/ns/}source property is required when creating subscriptions');
} }


$propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments']; $propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments'];


foreach($this->subscriptionPropertyMap as $xmlName=>$dbName) {
foreach ($this->subscriptionPropertyMap as $xmlName=>$dbName) {
if (array_key_exists($xmlName, $properties)) { if (array_key_exists($xmlName, $properties)) {
$values[$dbName] = $properties[$xmlName];
if (in_array($dbName, $propertiesBoolean)) {
$values[$dbName] = true;
$values[$dbName] = $properties[$xmlName];
if (in_array($dbName, $propertiesBoolean)) {
$values[$dbName] = true;
} }
} }
} }
* @suppress SqlInjectionChecker * @suppress SqlInjectionChecker
*/ */
$propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) { $propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) {

$newValues = []; $newValues = [];


foreach($mutations as $propertyName=>$propertyValue) {
foreach ($mutations as $propertyName=>$propertyValue) {
if ($propertyName === '{http://calendarserver.org/ns/}source') { if ($propertyName === '{http://calendarserver.org/ns/}source') {
$newValues['source'] = $propertyValue->getHref(); $newValues['source'] = $propertyValue->getHref();
} else { } else {
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$query->update('calendarsubscriptions') $query->update('calendarsubscriptions')
->set('lastmodified', $query->createNamedParameter(time())); ->set('lastmodified', $query->createNamedParameter(time()));
foreach($newValues as $fieldName=>$value) {
foreach ($newValues as $fieldName=>$value) {
$query->set($fieldName, $query->createNamedParameter($value)); $query->set($fieldName, $query->createNamedParameter($value));
} }
$query->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId))) $query->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
])); ]));


return true; return true;

}); });
} }




$row = $stmt->fetch(\PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);


if(!$row) {
if (!$row) {
return null; return null;
} }


->execute(); ->execute();


$result = []; $result = [];
foreach($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$result[] = [ $result[] = [
'calendardata' => $row['calendardata'], 'calendardata' => $row['calendardata'],
'uri' => $row['uri'], 'uri' => $row['uri'],
$stmt->execute([ $stmt->execute([
$calendarId $calendarId
]); ]);

} }


/** /**
* @return array * @return array
*/ */
public function getDenormalizedData($calendarData) { public function getDenormalizedData($calendarData) {

$vObject = Reader::read($calendarData); $vObject = Reader::read($calendarData);
$componentType = null; $componentType = null;
$component = null; $component = null;
$lastOccurrence = null; $lastOccurrence = null;
$uid = null; $uid = null;
$classification = self::CLASSIFICATION_PUBLIC; $classification = self::CLASSIFICATION_PUBLIC;
foreach($vObject->getComponents() as $component) {
foreach ($vObject->getComponents() as $component) {
if ($component->name!=='VTIMEZONE') { if ($component->name!=='VTIMEZONE') {
$componentType = $component->name; $componentType = $component->name;
$uid = (string)$component->UID; $uid = (string)$component->UID;
$lastOccurrence = $maxDate->getTimestamp(); $lastOccurrence = $maxDate->getTimestamp();
} else { } else {
$end = $it->getDtEnd(); $end = $it->getDtEnd();
while($it->valid() && $end < $maxDate) {
while ($it->valid() && $end < $maxDate) {
$end = $it->getDtEnd(); $end = $it->getDtEnd();
$it->next(); $it->next();

} }
$lastOccurrence = $end->getTimestamp(); $lastOccurrence = $end->getTimestamp();
} }

} }
} }


'uid' => $uid, 'uid' => $uid,
'classification' => $classification 'classification' => $classification
]; ];

} }


/** /**
* @return string|null * @return string|null
*/ */
public function setPublishStatus($value, $calendar) { public function setPublishStatus($value, $calendar) {

$calendarId = $calendar->getResourceId(); $calendarId = $calendar->getResourceId();
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', new GenericEvent( $this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', new GenericEvent(
'\OCA\DAV\CalDAV\CalDavBackend::updateShares', '\OCA\DAV\CalDAV\CalDavBackend::updateShares',
->execute(); ->execute();


$ids = $result->fetchAll(); $ids = $result->fetchAll();
foreach($ids as $id) {
foreach ($ids as $id) {
$this->deleteCalendar($id['id']); $this->deleteCalendar($id['id']);
} }
} }
$stmt = $query->execute(); $stmt = $query->execute();


$uris = []; $uris = [];
foreach($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
$uris[] = $row['uri']; $uris[] = $row['uri'];
} }
$stmt->closeCursor(); $stmt->closeCursor();
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION))) ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
->execute(); ->execute();


foreach($uris as $uri) {
foreach ($uris as $uri) {
$this->addChange($subscriptionId, $uri, 3, self::CALENDAR_TYPE_SUBSCRIPTION); $this->addChange($subscriptionId, $uri, 3, self::CALENDAR_TYPE_SUBSCRIPTION);
} }
} }
* @param string $uriOrigin * @param string $uriOrigin
* @param string $uriDestination * @param string $uriDestination
*/ */
public function moveCalendar($uriName, $uriOrigin, $uriDestination)
{
public function moveCalendar($uriName, $uriOrigin, $uriDestination) {
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$query->update('calendars') $query->update('calendars')
->set('principaluri', $query->createNamedParameter($uriDestination)) ->set('principaluri', $query->createNamedParameter($uriDestination))

+ 0
- 7
apps/dav/lib/CalDAV/Calendar.php View File

} }


public function getChild($name) { public function getChild($name) {

$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name); $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);


if (!$obj) { if (!$obj) {
$obj['acl'] = $this->getChildACL(); $obj['acl'] = $this->getChildACL();


return new CalendarObject($this->caldavBackend, $this->l10n, $this->calendarInfo, $obj); return new CalendarObject($this->caldavBackend, $this->l10n, $this->calendarInfo, $obj);

} }


public function getChildren() { public function getChildren() {

$objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']); $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
$children = []; $children = [];
foreach ($objs as $obj) { foreach ($objs as $obj) {
$children[] = new CalendarObject($this->caldavBackend, $this->l10n, $this->calendarInfo, $obj); $children[] = new CalendarObject($this->caldavBackend, $this->l10n, $this->calendarInfo, $obj);
} }
return $children; return $children;

} }


public function getMultipleChildren(array $paths) { public function getMultipleChildren(array $paths) {

$objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths); $objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths);
$children = []; $children = [];
foreach ($objs as $obj) { foreach ($objs as $obj) {
$children[] = new CalendarObject($this->caldavBackend, $this->l10n, $this->calendarInfo, $obj); $children[] = new CalendarObject($this->caldavBackend, $this->l10n, $this->calendarInfo, $obj);
} }
return $children; return $children;

} }


public function childExists($name) { public function childExists($name) {
} }


public function calendarQuery(array $filters) { public function calendarQuery(array $filters) {

$uris = $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters); $uris = $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
if ($this->isShared()) { if ($this->isShared()) {
return array_filter($uris, function ($uri) { return array_filter($uris, function ($uri) {

+ 1
- 1
apps/dav/lib/CalDAV/CalendarImpl.php View File

$permissions = $this->calendar->getACL(); $permissions = $this->calendar->getACL();
$result = 0; $result = 0;
foreach ($permissions as $permission) { foreach ($permissions as $permission) {
switch($permission['privilege']) {
switch ($permission['privilege']) {
case '{DAV:}read': case '{DAV:}read':
$result |= Constants::PERMISSION_READ; $result |= Constants::PERMISSION_READ;
break; break;

+ 1
- 1
apps/dav/lib/CalDAV/CalendarManager.php View File

* @param array $calendars * @param array $calendars
*/ */
private function register(IManager $cm, array $calendars) { private function register(IManager $cm, array $calendars) {
foreach($calendars as $calendarInfo) {
foreach ($calendars as $calendarInfo) {
$calendar = new Calendar($this->backend, $calendarInfo, $this->l10n, $this->config); $calendar = new Calendar($this->backend, $calendarInfo, $this->l10n, $this->config);
$cm->registerCalendar(new CalendarImpl( $cm->registerCalendar(new CalendarImpl(
$calendar, $calendar,

+ 6
- 6
apps/dav/lib/CalDAV/CalendarObject.php View File

private function createConfidentialObject(Component\VCalendar $vObject) { private function createConfidentialObject(Component\VCalendar $vObject) {
/** @var Component $vElement */ /** @var Component $vElement */
$vElement = null; $vElement = null;
if(isset($vObject->VEVENT)) {
if (isset($vObject->VEVENT)) {
$vElement = $vObject->VEVENT; $vElement = $vObject->VEVENT;
} }
if(isset($vObject->VJOURNAL)) {
if (isset($vObject->VJOURNAL)) {
$vElement = $vObject->VJOURNAL; $vElement = $vObject->VJOURNAL;
} }
if(isset($vObject->VTODO)) {
if (isset($vObject->VTODO)) {
$vElement = $vObject->VTODO; $vElement = $vObject->VTODO;
} }
if(!is_null($vElement)) {
if (!is_null($vElement)) {
foreach ($vElement->children() as &$property) { foreach ($vElement->children() as &$property) {
/** @var Property $property */ /** @var Property $property */
switch($property->name) {
switch ($property->name) {
case 'CREATED': case 'CREATED':
case 'DTSTART': case 'DTSTART':
case 'RRULE': case 'RRULE':
private function removeVAlarms(Component\VCalendar $vObject) { private function removeVAlarms(Component\VCalendar $vObject) {
$subcomponents = $vObject->getComponents(); $subcomponents = $vObject->getComponents();


foreach($subcomponents as $subcomponent) {
foreach ($subcomponents as $subcomponent) {
unset($subcomponent->VALARM); unset($subcomponent->VALARM);
} }
} }

+ 0
- 1
apps/dav/lib/CalDAV/CalendarRoot.php View File

namespace OCA\DAV\CalDAV; namespace OCA\DAV\CalDAV;


class CalendarRoot extends \Sabre\CalDAV\CalendarRoot { class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {

function getChildForPrincipal(array $principal) { function getChildForPrincipal(array $principal) {
return new CalendarHome($this->caldavBackend, $principal); return new CalendarHome($this->caldavBackend, $principal);
} }

+ 0
- 1
apps/dav/lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php View File



return $vcalendar; return $vcalendar;
} }

} }

+ 0
- 1
apps/dav/lib/CalDAV/Integration/ExternalCalendar.php View File

*/ */
final public function createDirectory($name) { final public function createDirectory($name) {
throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed'); throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed');

} }


/** /**

+ 0
- 1
apps/dav/lib/CalDAV/Integration/ICalendarProvider.php View File

* @return ExternalCalendar|null Calendar if it exists, null otherwise * @return ExternalCalendar|null Calendar if it exists, null otherwise
*/ */
public function getCalendarInCalendarHome(string $principalUri, string $calendarUri): ?ExternalCalendar; public function getCalendarInCalendarHome(string $principalUri, string $calendarUri): ?ExternalCalendar;

} }

+ 0
- 2
apps/dav/lib/CalDAV/Plugin.php View File

namespace OCA\DAV\CalDAV; namespace OCA\DAV\CalDAV;


class Plugin extends \Sabre\CalDAV\Plugin { class Plugin extends \Sabre\CalDAV\Plugin {

const SYSTEM_CALENDAR_ROOT = 'system-calendars'; const SYSTEM_CALENDAR_ROOT = 'system-calendars';


/** /**
return self::SYSTEM_CALENDAR_ROOT . '/calendar-rooms/' . $principalId; return self::SYSTEM_CALENDAR_ROOT . '/calendar-rooms/' . $principalId;
} }
} }

} }

+ 0
- 1
apps/dav/lib/CalDAV/Principal/Collection.php View File

function getChildForPrincipal(array $principalInfo) { function getChildForPrincipal(array $principalInfo) {
return new User($this->principalBackend, $principalInfo); return new User($this->principalBackend, $principalInfo);
} }

} }

+ 0
- 1
apps/dav/lib/CalDAV/Principal/User.php View File

]; ];
return $acl; return $acl;
} }

} }

+ 0
- 1
apps/dav/lib/CalDAV/Proxy/ProxyMapper.php View File

* @package OCA\DAV\CalDAV\Proxy * @package OCA\DAV\CalDAV\Proxy
*/ */
class ProxyMapper extends QBMapper { class ProxyMapper extends QBMapper {

const PERMISSION_READ = 1; const PERMISSION_READ = 1;
const PERMISSION_WRITE = 2; const PERMISSION_WRITE = 2;



+ 0
- 1
apps/dav/lib/CalDAV/PublicCalendarRoot.php View File

$this->caldavBackend = $caldavBackend; $this->caldavBackend = $caldavBackend;
$this->l10n = $l10n; $this->l10n = $l10n;
$this->config = $config; $this->config = $config;

} }


/** /**

+ 1
- 1
apps/dav/lib/CalDAV/Reminder/NotificationProvider/AbstractProvider.php View File

* *
* @package OCA\DAV\CalDAV\Reminder\NotificationProvider * @package OCA\DAV\CalDAV\Reminder\NotificationProvider
*/ */
abstract class AbstractProvider implements INotificationProvider {
abstract class AbstractProvider implements INotificationProvider {


/** @var string */ /** @var string */
public const NOTIFICATION_TYPE = ''; public const NOTIFICATION_TYPE = '';

+ 4
- 4
apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php View File

$sortedByLanguage = $this->sortEMailAddressesByLanguage($emailAddresses, $fallbackLanguage); $sortedByLanguage = $this->sortEMailAddressesByLanguage($emailAddresses, $fallbackLanguage);
$organizer = $this->getOrganizerEMailAndNameFromEvent($vevent); $organizer = $this->getOrganizerEMailAndNameFromEvent($vevent);


foreach($sortedByLanguage as $lang => $emailAddresses) {
foreach ($sortedByLanguage as $lang => $emailAddresses) {
if (!$this->hasL10NForLang($lang)) { if (!$this->hasL10NForLang($lang)) {
$lang = $fallbackLanguage; $lang = $fallbackLanguage;
} }
string $defaultLanguage):array { string $defaultLanguage):array {
$sortedByLanguage = []; $sortedByLanguage = [];


foreach($emails as $emailAddress => $parameters) {
foreach ($emails as $emailAddress => $parameters) {
if (isset($parameters['LANG'])) { if (isset($parameters['LANG'])) {
$lang = $parameters['LANG']; $lang = $parameters['LANG'];
} else { } else {
} }


$emailAddressesOfDelegates = $delegates->getParts(); $emailAddressesOfDelegates = $delegates->getParts();
foreach($emailAddressesOfDelegates as $addressesOfDelegate) {
foreach ($emailAddressesOfDelegates as $addressesOfDelegate) {
if (strcasecmp($addressesOfDelegate, 'mailto:') === 0) { if (strcasecmp($addressesOfDelegate, 'mailto:') === 0) {
$emailAddresses[substr($addressesOfDelegate, 7)] = []; $emailAddresses[substr($addressesOfDelegate, 7)] = [];
} }
private function getEMailAddressesOfAllUsersWithWriteAccessToCalendar(array $users):array { private function getEMailAddressesOfAllUsersWithWriteAccessToCalendar(array $users):array {
$emailAddresses = []; $emailAddresses = [];


foreach($users as $user) {
foreach ($users as $user) {
$emailAddress = $user->getEMailAddress(); $emailAddress = $user->getEMailAddress();
if ($emailAddress) { if ($emailAddress) {
$lang = $this->getLangForUser($user); $lang = $this->getLangForUser($user);

+ 0
- 1
apps/dav/lib/CalDAV/Reminder/NotificationProvider/ProviderNotAvailableException.php View File

public function __construct(string $type) { public function __construct(string $type) {
parent::__construct("No notification provider for type $type available"); parent::__construct("No notification provider for type $type available");
} }

} }

+ 1
- 1
apps/dav/lib/CalDAV/Reminder/NotificationProvider/PushProvider.php View File

// Empty Notification ObjectId will be catched by OC\Notification\Notification // Empty Notification ObjectId will be catched by OC\Notification\Notification
$eventUUIDHash = $eventUUID ? hash('sha256', $eventUUID, false) : ''; $eventUUIDHash = $eventUUID ? hash('sha256', $eventUUID, false) : '';


foreach($users as $user) {
foreach ($users as $user) {
/** @var INotification $notification */ /** @var INotification $notification */
$notification = $this->manager->createNotification(); $notification = $this->manager->createNotification();
$notification->setApp(Application::APP_ID) $notification->setApp(Application::APP_ID)

+ 0
- 1
apps/dav/lib/CalDAV/Reminder/NotificationTypeDoesNotExistException.php View File

public function __construct(string $type) { public function __construct(string $type) {
parent::__construct("Type $type is not an accepted type of notification"); parent::__construct("Type $type is not an accepted type of notification");
} }

} }

+ 1
- 1
apps/dav/lib/CalDAV/Reminder/Notifier.php View File

$this->l10n = $this->l10nFactory->get('dav', $languageCode); $this->l10n = $this->l10nFactory->get('dav', $languageCode);


// Handle notifier subjects // Handle notifier subjects
switch($notification->getSubject()) {
switch ($notification->getSubject()) {
case 'calendar_reminder': case 'calendar_reminder':
return $this->prepareReminderNotification($notification); return $this->prepareReminderNotification($notification);



+ 14
- 15
apps/dav/lib/CalDAV/Reminder/ReminderService.php View File

public function processReminders():void { public function processReminders():void {
$reminders = $this->backend->getRemindersToProcess(); $reminders = $this->backend->getRemindersToProcess();


foreach($reminders as $reminder) {
foreach ($reminders as $reminder) {
$calendarData = is_resource($reminder['calendardata']) $calendarData = is_resource($reminder['calendardata'])
? stream_get_contents($reminder['calendardata']) ? stream_get_contents($reminder['calendardata'])
: $reminder['calendardata']; : $reminder['calendardata'];
return; return;
} }


switch($action) {
switch ($action) {
case '\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject': case '\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject':
$this->onCalendarObjectCreate($objectData); $this->onCalendarObjectCreate($objectData);
break; break;
$now = $this->timeFactory->getDateTime(); $now = $this->timeFactory->getDateTime();
$isRecurring = $masterItem ? $this->isRecurring($masterItem) : false; $isRecurring = $masterItem ? $this->isRecurring($masterItem) : false;


foreach($recurrenceExceptions as $recurrenceException) {
foreach ($recurrenceExceptions as $recurrenceException) {
$eventHash = $this->getEventHash($recurrenceException); $eventHash = $this->getEventHash($recurrenceException);


if (!isset($recurrenceException->VALARM)) { if (!isset($recurrenceException->VALARM)) {
continue; continue;
} }


foreach($recurrenceException->VALARM as $valarm) {
foreach ($recurrenceException->VALARM as $valarm) {
/** @var VAlarm $valarm */ /** @var VAlarm $valarm */
$alarmHash = $this->getAlarmHash($valarm); $alarmHash = $this->getAlarmHash($valarm);
$triggerTime = $valarm->getEffectiveTriggerTime(); $triggerTime = $valarm->getEffectiveTriggerTime();
return; return;
} }


foreach($masterItem->VALARM as $valarm) {
foreach ($masterItem->VALARM as $valarm) {
$masterAlarms[] = $this->getAlarmHash($valarm); $masterAlarms[] = $this->getAlarmHash($valarm);
} }


return; return;
} }


while($iterator->valid() && count($processedAlarms) < count($masterAlarms)) {
while ($iterator->valid() && count($processedAlarms) < count($masterAlarms)) {
$event = $iterator->getEventObject(); $event = $iterator->getEventObject();


// Recurrence-exceptions are handled separately, so just ignore them here // Recurrence-exceptions are handled separately, so just ignore them here
continue; continue;
} }


foreach($event->VALARM as $valarm) {
foreach ($event->VALARM as $valarm) {
/** @var VAlarm $valarm */ /** @var VAlarm $valarm */
$alarmHash = $this->getAlarmHash($valarm); $alarmHash = $this->getAlarmHash($valarm);
if (\in_array($alarmHash, $processedAlarms, true)) { if (\in_array($alarmHash, $processedAlarms, true)) {
]; ];


$repeat = isset($valarm->REPEAT) ? (int) $valarm->REPEAT->getValue() : 0; $repeat = isset($valarm->REPEAT) ? (int) $valarm->REPEAT->getValue() : 0;
for($i = 0; $i < $repeat; $i++) {
for ($i = 0; $i < $repeat; $i++) {
if ($valarm->DURATION === null) { if ($valarm->DURATION === null) {
continue; continue;
} }
* @param array $reminders * @param array $reminders
*/ */
private function writeRemindersToDatabase(array $reminders): void { private function writeRemindersToDatabase(array $reminders): void {
foreach($reminders as $reminder) {
foreach ($reminders as $reminder) {
$this->backend->insertReminder( $this->backend->insertReminder(
(int) $reminder['calendar_id'], (int) $reminder['calendar_id'],
(int) $reminder['object_id'], (int) $reminder['object_id'],
!$reminder['is_recurring'] || !$reminder['is_recurring'] ||
!$reminder['is_relative'] || !$reminder['is_relative'] ||
$reminder['is_recurrence_exception']) { $reminder['is_recurrence_exception']) {

$this->backend->removeReminder($reminder['id']); $this->backend->removeReminder($reminder['id']);
return; return;
} }
return; return;
} }


while($iterator->valid()) {
while ($iterator->valid()) {
$event = $iterator->getEventObject(); $event = $iterator->getEventObject();


// Recurrence-exceptions are handled separately, so just ignore them here // Recurrence-exceptions are handled separately, so just ignore them here
continue; continue;
} }


foreach($event->VALARM as $valarm) {
foreach ($event->VALARM as $valarm) {
/** @var VAlarm $valarm */ /** @var VAlarm $valarm */
$alarmHash = $this->getAlarmHash($valarm); $alarmHash = $this->getAlarmHash($valarm);
if ($alarmHash !== $reminder['alarm_hash']) { if ($alarmHash !== $reminder['alarm_hash']) {


// Handle recurrence-exceptions first, because recurrence-expansion is expensive // Handle recurrence-exceptions first, because recurrence-expansion is expensive
if ($isRecurrenceException) { if ($isRecurrenceException) {
foreach($recurrenceExceptions as $recurrenceException) {
foreach ($recurrenceExceptions as $recurrenceException) {
if ($this->getEffectiveRecurrenceIdOfVEvent($recurrenceException) === $recurrenceId) { if ($this->getEffectiveRecurrenceIdOfVEvent($recurrenceException) === $recurrenceId) {
return $recurrenceException; return $recurrenceException;
} }
try { try {
return VObject\Reader::read($calendarData, return VObject\Reader::read($calendarData,
VObject\Reader::OPTION_FORGIVING); VObject\Reader::OPTION_FORGIVING);
} catch(ParseException $ex) {
} catch (ParseException $ex) {
return null; return null;
} }
} }
private function getAllVEventsFromVCalendar(VObject\Component\VCalendar $vcalendar):array { private function getAllVEventsFromVCalendar(VObject\Component\VCalendar $vcalendar):array {
$vevents = []; $vevents = [];


foreach($vcalendar->children() as $child) {
foreach ($vcalendar->children() as $child) {
if (!($child instanceof VObject\Component)) { if (!($child instanceof VObject\Component)) {
continue; continue;
} }

+ 11
- 12
apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php View File

$metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC); $metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC);


$metaDataById = []; $metaDataById = [];
foreach($metaDataRows as $metaDataRow) {
foreach ($metaDataRows as $metaDataRow) {
if (!isset($metaDataById[$metaDataRow[$this->dbForeignKeyName]])) { if (!isset($metaDataById[$metaDataRow[$this->dbForeignKeyName]])) {
$metaDataById[$metaDataRow[$this->dbForeignKeyName]] = []; $metaDataById[$metaDataRow[$this->dbForeignKeyName]] = [];
} }
$metaDataRow['value']; $metaDataRow['value'];
} }


while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$id = $row['id']; $id = $row['id'];


if (isset($metaDataById[$id])) { if (isset($metaDataById[$id])) {
} else { } else {
$principals[] = $this->rowToPrincipal($row); $principals[] = $this->rowToPrincipal($row);
} }

} }


$stmt->closeCursor(); $stmt->closeCursor();
$stmt = $query->execute(); $stmt = $query->execute();
$row = $stmt->fetch(\PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);


if(!$row) {
if (!$row) {
return null; return null;
} }


$metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC); $metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC);
$metadata = []; $metadata = [];


foreach($metaDataRows as $metaDataRow) {
foreach ($metaDataRows as $metaDataRow) {
$metadata[$metaDataRow['key']] = $metaDataRow['value']; $metadata[$metaDataRow['key']] = $metaDataRow['value'];
} }


$stmt = $query->execute(); $stmt = $query->execute();
$row = $stmt->fetch(\PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);


if(!$row) {
if (!$row) {
return null; return null;
} }


$metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC); $metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC);
$metadata = []; $metadata = [];


foreach($metaDataRows as $metaDataRow) {
foreach ($metaDataRows as $metaDataRow) {
$metadata[$metaDataRow['key']] = $metaDataRow['value']; $metadata[$metaDataRow['key']] = $metaDataRow['value'];
} }




$stmt = $query->execute(); $stmt = $query->execute();
$principals = []; $principals = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
if (!$this->isAllowedToAccessResource($row, $usersGroups)) { if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
continue; continue;
} }


$stmt = $query->execute(); $stmt = $query->execute();
$principals = []; $principals = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
if (!$this->isAllowedToAccessResource($row, $usersGroups)) { if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
continue; continue;
} }
$stmt = $query->execute(); $stmt = $query->execute();


$rows = []; $rows = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$id = $row[$this->dbForeignKeyName]; $id = $row[$this->dbForeignKeyName];


$principalRow = $this->getPrincipalById($id); $principalRow = $this->getPrincipalById($id);
$stmt = $query->execute(); $stmt = $query->execute();
$row = $stmt->fetch(\PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);


if(!$row) {
if (!$row) {
return null; return null;
} }
if (!$this->isAllowedToAccessResource($row, $usersGroups)) { if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
$stmt = $query->execute(); $stmt = $query->execute();
$row = $stmt->fetch(\PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);


if(!$row) {
if (!$row) {
return null; return null;
} }
if (!$this->isAllowedToAccessResource($row, $usersGroups)) { if (!$this->isAllowedToAccessResource($row, $usersGroups)) {

+ 2
- 3
apps/dav/lib/CalDAV/Schedule/IMipPlugin.php View File

$this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => implode(', ', $failed)]); $this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => implode(', ', $failed)]);
$iTipMessage->scheduleStatus = '5.0; EMail delivery failed'; $iTipMessage->scheduleStatus = '5.0; EMail delivery failed';
} }
} catch(\Exception $ex) {
} catch (\Exception $ex) {
$this->logger->logException($ex, ['app' => 'dav']); $this->logger->logException($ex, ['app' => 'dav']);
$iTipMessage->scheduleStatus = '5.0; EMail delivery failed'; $iTipMessage->scheduleStatus = '5.0; EMail delivery failed';
} }
$lastOccurrence = $maxDate->getTimestamp(); $lastOccurrence = $maxDate->getTimestamp();
} else { } else {
$end = $it->getDtEnd(); $end = $it->getDtEnd();
while($it->valid() && $end < $maxDate) {
while ($it->valid() && $end < $maxDate) {
$end = $it->getDtEnd(); $end = $it->getDtEnd();
$it->next(); $it->next();

} }
$lastOccurrence = $end->getTimestamp(); $lastOccurrence = $end->getTimestamp();
} }

+ 0
- 1
apps/dav/lib/CalDAV/Search/SearchPlugin.php View File

// If we're dealing with the calendar home, the calendar home itself is // If we're dealing with the calendar home, the calendar home itself is
// responsible for the calendar-query // responsible for the calendar-query
if ($node instanceof CalendarHome && $depth === 2) { if ($node instanceof CalendarHome && $depth === 2) {

$nodePaths = $node->calendarSearch($report->filters, $report->limit, $report->offset); $nodePaths = $node->calendarSearch($report->filters, $report->limit, $report->offset);


foreach ($nodePaths as $path) { foreach ($nodePaths as $path) {

+ 0
- 1
apps/dav/lib/CalDAV/Search/Xml/Filter/ParamFilter.php View File



if (!is_string($property)) { if (!is_string($property)) {
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute'); throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute');

} }
if (!is_string($parameter)) { if (!is_string($parameter)) {
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute'); throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute');

+ 1
- 1
apps/dav/lib/CalDAV/WebcalCaching/Plugin.php View File

} }


$calendarHome->enableCachedSubscriptionsForThisRequest(); $calendarHome->enableCachedSubscriptionsForThisRequest();
} catch(NotFound $ex) {
} catch (NotFound $ex) {
return; return;
} }
} }

+ 8
- 8
apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php View File

$calendarData = $vObject->serialize(); $calendarData = $vObject->serialize();
try { try {
$this->calDavBackend->createCalendarObject($subscription['id'], $uri, $calendarData, CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION); $this->calDavBackend->createCalendarObject($subscription['id'], $uri, $calendarData, CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION);
} catch(BadRequest $ex) {
} catch (BadRequest $ex) {
$this->logger->logException($ex); $this->logger->logException($ex);
} }
} }
} }


$this->updateSubscription($subscription, $mutations); $this->updateSubscription($subscription, $mutations);
} catch(ParseException $ex) {
} catch (ParseException $ex) {
$subscriptionId = $subscription['id']; $subscriptionId = $subscription['id'];


$this->logger->logException($ex); $this->logger->logException($ex);


$contentType = $response->getHeader('Content-Type'); $contentType = $response->getHeader('Content-Type');
$contentType = explode(';', $contentType, 2)[0]; $contentType = explode(';', $contentType, 2)[0];
switch($contentType) {
switch ($contentType) {
case 'application/calendar+json': case 'application/calendar+json':
try { try {
$jCalendar = Reader::readJson($body, Reader::OPTION_FORGIVING); $jCalendar = Reader::readJson($body, Reader::OPTION_FORGIVING);
} catch(Exception $ex) {
} catch (Exception $ex) {
// In case of a parsing error return null // In case of a parsing error return null
$this->logger->debug("Subscription $subscriptionId could not be parsed"); $this->logger->debug("Subscription $subscriptionId could not be parsed");
return null; return null;
case 'application/calendar+xml': case 'application/calendar+xml':
try { try {
$xCalendar = Reader::readXML($body); $xCalendar = Reader::readXML($body);
} catch(Exception $ex) {
} catch (Exception $ex) {
// In case of a parsing error return null // In case of a parsing error return null
$this->logger->debug("Subscription $subscriptionId could not be parsed"); $this->logger->debug("Subscription $subscriptionId could not be parsed");
return null; return null;
default: default:
try { try {
$vCalendar = Reader::read($body); $vCalendar = Reader::read($body);
} catch(Exception $ex) {
} catch (Exception $ex) {
// In case of a parsing error return null // In case of a parsing error return null
$this->logger->debug("Subscription $subscriptionId could not be parsed"); $this->logger->debug("Subscription $subscriptionId could not be parsed");
return null; return null;
} }
return $vCalendar->serialize(); return $vCalendar->serialize();
} }
} catch(Exception $ex) {
} catch (Exception $ex) {
$this->logger->logException($ex); $this->logger->logException($ex);
$this->logger->warning("Subscription $subscriptionId could not be refreshed due to a network error"); $this->logger->warning("Subscription $subscriptionId could not be refreshed due to a network error");


// check if new refresh rate is even valid // check if new refresh rate is even valid
try { try {
DateTimeParser::parseDuration($newRefreshRate); DateTimeParser::parseDuration($newRefreshRate);
} catch(InvalidDataException $ex) {
} catch (InvalidDataException $ex) {
return null; return null;
} }



+ 0
- 1
apps/dav/lib/Capabilities.php View File

use OCP\Capabilities\ICapability; use OCP\Capabilities\ICapability;


class Capabilities implements ICapability { class Capabilities implements ICapability {

public function getCapabilities() { public function getCapabilities() {
return [ return [
'dav' => [ 'dav' => [

+ 0
- 2
apps/dav/lib/CardDAV/AddressBook.php View File

} }


public function getChild($name) { public function getChild($name) {

$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name); $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
if (!$obj) { if (!$obj) {
throw new NotFound('Card not found'); throw new NotFound('Card not found');
} }
$obj['acl'] = $this->getChildACL(); $obj['acl'] = $this->getChildACL();
return new Card($this->carddavBackend, $this->addressBookInfo, $obj); return new Card($this->carddavBackend, $this->addressBookInfo, $obj);

} }


/** /**

+ 2
- 7
apps/dav/lib/CardDAV/AddressBookImpl.php View File

array $addressBookInfo, array $addressBookInfo,
CardDavBackend $backend, CardDavBackend $backend,
IURLGenerator $urlGenerator) { IURLGenerator $urlGenerator) {

$this->addressBook = $addressBook; $this->addressBook = $addressBook;
$this->addressBookInfo = $addressBookInfo; $this->addressBookInfo = $addressBookInfo;
$this->backend = $backend; $this->backend = $backend;
} }


return $this->vCard2Array($uri, $vCard); return $this->vCard2Array($uri, $vCard);

} }


/** /**
$permissions = $this->addressBook->getACL(); $permissions = $this->addressBook->getACL();
$result = 0; $result = 0;
foreach ($permissions as $permission) { foreach ($permissions as $permission) {
switch($permission['privilege']) {
switch ($permission['privilege']) {
case '{DAV:}read': case '{DAV:}read':
$result |= Constants::PERMISSION_READ; $result |= Constants::PERMISSION_READ;
break; break;
]) . '?photo'; ]) . '?photo';


$result['PHOTO'] = 'VALUE=uri:' . $url; $result['PHOTO'] = 'VALUE=uri:' . $url;

} elseif ($property->name === 'X-SOCIALPROFILE') { } elseif ($property->name === 'X-SOCIALPROFILE') {
$type = $this->getTypeFromProperty($property); $type = $this->getTypeFromProperty($property);


$result[$property->name][$type] = $property->getValue(); $result[$property->name][$type] = $property->getValue();
} }


// The following properties can be set multiple times
// The following properties can be set multiple times
} elseif (in_array($property->name, ['CLOUD', 'EMAIL', 'IMPP', 'TEL', 'URL', 'X-ADDRESSBOOKSERVER-MEMBER'])) { } elseif (in_array($property->name, ['CLOUD', 'EMAIL', 'IMPP', 'TEL', 'URL', 'X-ADDRESSBOOKSERVER-MEMBER'])) {
if (!isset($result[$property->name])) { if (!isset($result[$property->name])) {
$result[$property->name] = []; $result[$property->name] = [];
} else { } else {
$result[$property->name][] = $property->getValue(); $result[$property->name][] = $property->getValue();
} }


} else { } else {
$result[$property->name] = $property->getValue(); $result[$property->name] = $property->getValue();
} }

+ 0
- 3
apps/dav/lib/CardDAV/AddressBookRoot.php View File

} }


function getName() { function getName() {

if ($this->principalPrefix === 'principals') { if ($this->principalPrefix === 'principals') {
return parent::getName(); return parent::getName();
} }


// We are only interested in the second part. // We are only interested in the second part.
return $parts[1]; return $parts[1];

} }

} }

+ 19
- 30
apps/dav/lib/CardDAV/CardDavBackend.php View File

use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Component\EventDispatcher\GenericEvent;


class CardDavBackend implements BackendInterface, SyncSupport { class CardDavBackend implements BackendInterface, SyncSupport {

const PERSONAL_ADDRESSBOOK_URI = 'contacts'; const PERSONAL_ADDRESSBOOK_URI = 'contacts';
const PERSONAL_ADDRESSBOOK_NAME = 'Contacts'; const PERSONAL_ADDRESSBOOK_NAME = 'Contacts';


$addressBooks = []; $addressBooks = [];


$result = $query->execute(); $result = $query->execute();
while($row = $result->fetch()) {
while ($row = $result->fetch()) {
$addressBooks[$row['id']] = [ $addressBooks[$row['id']] = [
'id' => $row['id'], 'id' => $row['id'],
'uri' => $row['uri'], 'uri' => $row['uri'],
->execute(); ->execute();


$readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only'; $readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only';
while($row = $result->fetch()) {
while ($row = $result->fetch()) {
if ($row['principaluri'] === $principalUri) { if ($row['principaluri'] === $principalUri) {
continue; continue;
} }
$addressBooks = []; $addressBooks = [];


$result = $query->execute(); $result = $query->execute();
while($row = $result->fetch()) {
while ($row = $result->fetch()) {
$addressBooks[$row['id']] = [ $addressBooks[$row['id']] = [
'id' => $row['id'], 'id' => $row['id'],
'uri' => $row['uri'], 'uri' => $row['uri'],
* @suppress SqlInjectionChecker * @suppress SqlInjectionChecker
*/ */
$propPatch->handle($supportedProperties, function ($mutations) use ($addressBookId) { $propPatch->handle($supportedProperties, function ($mutations) use ($addressBookId) {

$updates = []; $updates = [];
foreach($mutations as $property=>$newValue) {

switch($property) {
foreach ($mutations as $property=>$newValue) {
switch ($property) {
case '{DAV:}displayname': case '{DAV:}displayname':
$updates['displayname'] = $newValue; $updates['displayname'] = $newValue;
break; break;
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$query->update('addressbooks'); $query->update('addressbooks');


foreach($updates as $key=>$value) {
foreach ($updates as $key=>$value) {
$query->set($key, $query->createNamedParameter($value)); $query->set($key, $query->createNamedParameter($value));
} }
$query->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId))) $query->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId)))
$this->addChange($addressBookId, "", 2); $this->addChange($addressBookId, "", 2);


return true; return true;

}); });
} }


'synctoken' => 1 'synctoken' => 1
]; ];


foreach($properties as $property=>$newValue) {

switch($property) {
foreach ($properties as $property=>$newValue) {
switch ($property) {
case '{DAV:}displayname': case '{DAV:}displayname':
$values['displayname'] = $newValue; $values['displayname'] = $newValue;
break; break;
default: default:
throw new BadRequest('Unknown property: ' . $property); throw new BadRequest('Unknown property: ' . $property);
} }

} }


// Fallback to make sure the displayname is set. Some clients may refuse // Fallback to make sure the displayname is set. Some clients may refuse
// to work with addressbooks not having a displayname. // to work with addressbooks not having a displayname.
if(is_null($values['displayname'])) {
if (is_null($values['displayname'])) {
$values['displayname'] = $url; $values['displayname'] = $url;
} }


$query->delete($this->dbCardsPropertiesTable) $query->delete($this->dbCardsPropertiesTable)
->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId)))
->execute(); ->execute();

} }


/** /**
$cards = []; $cards = [];


$result = $query->execute(); $result = $query->execute();
while($row = $result->fetch()) {
while ($row = $result->fetch()) {
$row['etag'] = '"' . $row['etag'] . '"'; $row['etag'] = '"' . $row['etag'] . '"';
$row['carddata'] = $this->readBlob($row['carddata']); $row['carddata'] = $this->readBlob($row['carddata']);
$cards[] = $row; $cards[] = $row;
* @return string * @return string
*/ */
function updateCard($addressBookId, $cardUri, $cardData) { function updateCard($addressBookId, $cardUri, $cardData) {

$uid = $this->getUID($cardData); $uid = $this->getUID($cardData);
$etag = md5($cardData); $etag = md5($cardData);
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
$stmt->execute([ $addressBookId ]); $stmt->execute([ $addressBookId ]);
$currentToken = $stmt->fetchColumn(0); $currentToken = $stmt->fetchColumn(0);


if (is_null($currentToken)) return null;
if (is_null($currentToken)) {
return null;
}


$result = [ $result = [
'syncToken' => $currentToken, 'syncToken' => $currentToken,
]; ];


if ($syncToken) { if ($syncToken) {

$query = "SELECT `uri`, `operation` FROM `*PREFIX*addressbookchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `addressbookid` = ? ORDER BY `synctoken`"; $query = "SELECT `uri`, `operation` FROM `*PREFIX*addressbookchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `addressbookid` = ? ORDER BY `synctoken`";
if ($limit>0) { if ($limit>0) {
$query .= " LIMIT " . (int)$limit; $query .= " LIMIT " . (int)$limit;


// This loop ensures that any duplicates are overwritten, only the // This loop ensures that any duplicates are overwritten, only the
// last change on a node is relevant. // last change on a node is relevant.
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {

while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$changes[$row['uri']] = $row['operation']; $changes[$row['uri']] = $row['operation'];

} }


foreach($changes as $uri => $operation) {

switch($operation) {
foreach ($changes as $uri => $operation) {
switch ($operation) {
case 1: case 1:
$result['added'][] = $uri; $result['added'][] = $uri;
break; break;
$result['deleted'][] = $uri; $result['deleted'][] = $uri;
break; break;
} }

} }
} else { } else {
// No synctoken supplied, this is the initial sync. // No synctoken supplied, this is the initial sync.


// No need for like when the pattern is empty // No need for like when the pattern is empty
if ('' !== $pattern) { if ('' !== $pattern) {
if(\array_key_exists('escape_like_param', $options) && $options['escape_like_param'] === false) {
if (\array_key_exists('escape_like_param', $options) && $options['escape_like_param'] === false) {
$query2->andWhere($query2->expr()->ilike('cp.value', $query->createNamedParameter($pattern))); $query2->andWhere($query2->expr()->ilike('cp.value', $query->createNamedParameter($pattern)));
} else { } else {
$query2->andWhere($query2->expr()->ilike('cp.value', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%'))); $query2->andWhere($query2->expr()->ilike('cp.value', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%')));
); );


foreach ($vCard->children() as $property) { foreach ($vCard->children() as $property) {
if(!in_array($property->name, self::$indexProperties)) {
if (!in_array($property->name, self::$indexProperties)) {
continue; continue;
} }
$preferred = 0; $preferred = 0;
foreach($property->parameters as $parameter) {
foreach ($property->parameters as $parameter) {
if ($parameter->name === 'TYPE' && strtoupper($parameter->getValue()) === 'PREF') { if ($parameter->name === 'TYPE' && strtoupper($parameter->getValue()) === 'PREF') {
$preferred = 1; $preferred = 1;
break; break;

+ 0
- 1
apps/dav/lib/CardDAV/ContactsManager.php View File

); );
} }
} }

} }

+ 0
- 3
apps/dav/lib/CardDAV/Converter.php View File

* @return VCard|null * @return VCard|null
*/ */
public function createCardFromUser(IUser $user) { public function createCardFromUser(IUser $user) {

$userData = $this->accountManager->getUser($user); $userData = $this->accountManager->getUser($user);


$uid = $user->getUID(); $uid = $user->getUID();
} }


foreach ($userData as $property => $value) { foreach ($userData as $property => $value) {

$shareWithTrustedServers = $shareWithTrustedServers =
$value['scope'] === AccountManager::VISIBILITY_CONTACTS_ONLY || $value['scope'] === AccountManager::VISIBILITY_CONTACTS_ONLY ||
$value['scope'] === AccountManager::VISIBILITY_PUBLIC; $value['scope'] === AccountManager::VISIBILITY_PUBLIC;
return null; return null;
} }
} }

} }

+ 0
- 3
apps/dav/lib/CardDAV/HasPhotoPlugin.php View File

* @return void * @return void
*/ */
function propFind(PropFind $propFind, INode $node) { function propFind(PropFind $propFind, INode $node) {

$ns = '{http://nextcloud.com/ns}'; $ns = '{http://nextcloud.com/ns}';


if ($node instanceof Card) { if ($node instanceof Card) {
'name' => $this->getPluginName(), 'name' => $this->getPluginName(),
'description' => 'Return a boolean stating if the vcard have a photo property set or not.' 'description' => 'Return a boolean stating if the vcard have a photo property set or not.'
]; ];

} }

} }

+ 0
- 1
apps/dav/lib/CardDAV/ImageExportPlugin.php View File

* @return bool * @return bool
*/ */
public function httpGet(RequestInterface $request, ResponseInterface $response) { public function httpGet(RequestInterface $request, ResponseInterface $response) {

$queryParams = $request->getQueryParameters(); $queryParams = $request->getQueryParameters();
// TODO: in addition to photo we should also add logo some point in time // TODO: in addition to photo we should also add logo some point in time
if (!array_key_exists('photo', $queryParams)) { if (!array_key_exists('photo', $queryParams)) {

+ 0
- 2
apps/dav/lib/CardDAV/Integration/ExternalAddressBook.php View File

*/ */
final public function createDirectory($name) { final public function createDirectory($name) {
throw new DAV\Exception\MethodNotAllowed('Creating collections in address book objects is not allowed'); throw new DAV\Exception\MethodNotAllowed('Creating collections in address book objects is not allowed');

} }


/** /**
public static function doesViolateReservedName(string $uri): bool { public static function doesViolateReservedName(string $uri): bool {
return strpos($uri, self::PREFIX) === 0; return strpos($uri, self::PREFIX) === 0;
} }

} }

+ 0
- 1
apps/dav/lib/CardDAV/Integration/IAddressBookProvider.php View File

*@since 19.0.0 *@since 19.0.0
*/ */
public function getAddressBookInAddressBookHome(string $principalUri, string $uri): ?ExternalAddressBook; public function getAddressBookInAddressBookHome(string $principalUri, string $uri): ?ExternalAddressBook;

} }

+ 0
- 3
apps/dav/lib/CardDAV/MultiGetExportPlugin.php View File

* @return bool * @return bool
*/ */
public function httpReport(RequestInterface $request, ResponseInterface $response) { public function httpReport(RequestInterface $request, ResponseInterface $response) {

$queryParams = $request->getQueryParameters(); $queryParams = $request->getQueryParameters();
if (!array_key_exists('export', $queryParams)) { if (!array_key_exists('export', $queryParams)) {
return; return;
'name' => $this->getPluginName(), 'name' => $this->getPluginName(),
'description' => 'Intercept a multi-get request and return a single vcf file instead.' 'description' => 'Intercept a multi-get request and return a single vcf file instead.'
]; ];

} }

} }

+ 1
- 2
apps/dav/lib/CardDAV/PhotoCache.php View File

$file = $folder->newFile($path); $file = $folder->newFile($path);
$file->putContent($photo->data()); $file->putContent($photo->data());
} catch (NotPermittedException $e) { } catch (NotPermittedException $e) {

} }
} }


try { try {
return $this->appData->getFolder($hash); return $this->appData->getFolder($hash);
} catch (NotFoundException $e) { } catch (NotFoundException $e) {
if($createIfNotExists) {
if ($createIfNotExists) {
return $this->appData->newFolder($hash); return $this->appData->newFolder($hash);
} else { } else {
throw $e; throw $e;

+ 0
- 3
apps/dav/lib/CardDAV/Plugin.php View File

use Sabre\DAV\Server; use Sabre\DAV\Server;


class Plugin extends \Sabre\CardDAV\Plugin { class Plugin extends \Sabre\CardDAV\Plugin {

function initialize(Server $server) { function initialize(Server $server) {
$server->on('propFind', [$this, 'propFind']); $server->on('propFind', [$this, 'propFind']);
parent::initialize($server); parent::initialize($server);
* @return void * @return void
*/ */
function propFind(PropFind $propFind, INode $node) { function propFind(PropFind $propFind, INode $node) {

$ns = '{http://owncloud.org/ns}'; $ns = '{http://owncloud.org/ns}';


if ($node instanceof AddressBook) { if ($node instanceof AddressBook) {

$propFind->handle($ns . 'groups', function () use ($node) { $propFind->handle($ns . 'groups', function () use ($node) {
return new Groups($node->getContactsGroups()); return new Groups($node->getContactsGroups());
}); });

+ 10
- 13
apps/dav/lib/CardDAV/SyncService.php View File

* @param string $syncToken * @param string $syncToken
* @return array * @return array
*/ */
protected function requestSyncReport($url, $userName, $addressBookUrl, $sharedSecret, $syncToken) {
$client = $this->getClient($url, $userName, $sharedSecret);
protected function requestSyncReport($url, $userName, $addressBookUrl, $sharedSecret, $syncToken) {
$client = $this->getClient($url, $userName, $sharedSecret);


$body = $this->buildSyncCollectionRequestBody($syncToken);
$body = $this->buildSyncCollectionRequestBody($syncToken);


$response = $client->request('REPORT', $addressBookUrl, $body, [
'Content-Type' => 'application/xml'
]);
$response = $client->request('REPORT', $addressBookUrl, $body, [
'Content-Type' => 'application/xml'
]);


return $this->parseMultiStatus($response['body']);
}
return $this->parseMultiStatus($response['body']);
}


/** /**
* @param string $url * @param string $url
* @return string * @return string
*/ */
private function buildSyncCollectionRequestBody($syncToken) { private function buildSyncCollectionRequestBody($syncToken) {

$dom = new \DOMDocument('1.0', 'UTF-8'); $dom = new \DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true; $dom->formatOutput = true;
$root = $dom->createElementNS('DAV:', 'd:sync-collection'); $root = $dom->createElementNS('DAV:', 'd:sync-collection');
*/ */
public function deleteUser($userOrCardId) { public function deleteUser($userOrCardId) {
$systemAddressBook = $this->getLocalSystemAddressBook(); $systemAddressBook = $this->getLocalSystemAddressBook();
if ($userOrCardId instanceof IUser){
if ($userOrCardId instanceof IUser) {
$name = $userOrCardId->getBackendClassName(); $name = $userOrCardId->getBackendClassName();
$userId = $userOrCardId->getUID(); $userId = $userOrCardId->getUID();




// remove no longer existing // remove no longer existing
$allCards = $this->backend->getCards($systemAddressBook['id']); $allCards = $this->backend->getCards($systemAddressBook['id']);
foreach($allCards as $card) {
foreach ($allCards as $card) {
$vCard = Reader::read($card['carddata']); $vCard = Reader::read($card['carddata']);
$uid = $vCard->UID->getValue(); $uid = $vCard->UID->getValue();
// load backend and see if user exists // load backend and see if user exists
} }
} }
} }


} }

+ 0
- 2
apps/dav/lib/CardDAV/UserAddressBooks.php View File

* @return array * @return array
*/ */
function getACL() { function getACL() {

$acl = parent::getACL(); $acl = parent::getACL();
if ($this->principalUri === 'principals/system/system') { if ($this->principalUri === 'principals/system/system') {
$acl[] = [ $acl[] = [


return $acl; return $acl;
} }

} }

+ 0
- 0
apps/dav/lib/Command/ListCalendars.php View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save