aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/composer/composer/installed.php4
-rw-r--r--lib/private/BackgroundJob/JobList.php2
-rw-r--r--lib/private/Share20/DefaultShareProvider.php192
-rw-r--r--lib/private/Share20/Manager.php121
-rw-r--r--lib/private/Share20/ProviderFactory.php1
-rw-r--r--lib/private/Share20/ShareAttributes.php12
-rw-r--r--lib/public/AppFramework/Http/Attribute/ARateLimit.php2
-rw-r--r--lib/public/Share/IAttributes.php17
-rw-r--r--lib/public/Share/IManager.php2
-rw-r--r--lib/public/Share/IShare.php4
-rw-r--r--lib/public/Share/IShareProviderWithNotification.php24
13 files changed, 203 insertions, 180 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index c4a4484f0a6..4ee453f0260 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -682,6 +682,7 @@ return array(
'OCP\\Share\\IShare' => $baseDir . '/lib/public/Share/IShare.php',
'OCP\\Share\\IShareHelper' => $baseDir . '/lib/public/Share/IShareHelper.php',
'OCP\\Share\\IShareProvider' => $baseDir . '/lib/public/Share/IShareProvider.php',
+ 'OCP\\Share\\IShareProviderWithNotification' => $baseDir . '/lib/public/Share/IShareProviderWithNotification.php',
'OCP\\Share_Backend' => $baseDir . '/lib/public/Share_Backend.php',
'OCP\\Share_Backend_Collection' => $baseDir . '/lib/public/Share_Backend_Collection.php',
'OCP\\Share_Backend_File_Dependent' => $baseDir . '/lib/public/Share_Backend_File_Dependent.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 34b31711323..d6cbb1ac886 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -715,6 +715,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Share\\IShare' => __DIR__ . '/../../..' . '/lib/public/Share/IShare.php',
'OCP\\Share\\IShareHelper' => __DIR__ . '/../../..' . '/lib/public/Share/IShareHelper.php',
'OCP\\Share\\IShareProvider' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProvider.php',
+ 'OCP\\Share\\IShareProviderWithNotification' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderWithNotification.php',
'OCP\\Share_Backend' => __DIR__ . '/../../..' . '/lib/public/Share_Backend.php',
'OCP\\Share_Backend_Collection' => __DIR__ . '/../../..' . '/lib/public/Share_Backend_Collection.php',
'OCP\\Share_Backend_File_Dependent' => __DIR__ . '/../../..' . '/lib/public/Share_Backend_File_Dependent.php',
diff --git a/lib/composer/composer/installed.php b/lib/composer/composer/installed.php
index efdbecf06c5..5fe8d8f7f49 100644
--- a/lib/composer/composer/installed.php
+++ b/lib/composer/composer/installed.php
@@ -3,7 +3,7 @@
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'e0b9ff4fa255b4dd4c1e3881e26dff18053e129a',
+ 'reference' => 'b99276fdfbac6b1ff243807b8b5b8161f0f67a24',
'type' => 'library',
'install_path' => __DIR__ . '/../../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'e0b9ff4fa255b4dd4c1e3881e26dff18053e129a',
+ 'reference' => 'b99276fdfbac6b1ff243807b8b5b8161f0f67a24',
'type' => 'library',
'install_path' => __DIR__ . '/../../../',
'aliases' => array(),
diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php
index 61c48b0eab2..201263320e3 100644
--- a/lib/private/BackgroundJob/JobList.php
+++ b/lib/private/BackgroundJob/JobList.php
@@ -220,7 +220,7 @@ class JobList implements IJobList {
$job = $this->buildJob($row);
if ($job instanceof IParallelAwareJob && !$job->getAllowParallelRuns() && $this->hasReservedJob(get_class($job))) {
- $this->logger->debug('Skipping ' . get_class($job) . ' job with ID ' . $job->getId() . ' because another job with the same class is already running', ['app' => 'cron']);
+ $this->logger->info('Skipping ' . get_class($job) . ' job with ID ' . $job->getId() . ' because another job with the same class is already running', ['app' => 'cron']);
$update = $this->connection->getQueryBuilder();
$update->update('jobs')
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index acf4e6bd9f4..658353b9a26 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -20,6 +20,7 @@ use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\IDBConnection;
use OCP\IGroupManager;
+use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
@@ -28,7 +29,7 @@ use OCP\Mail\IMailer;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IAttributes;
use OCP\Share\IShare;
-use OCP\Share\IShareProvider;
+use OCP\Share\IShareProviderWithNotification;
use Psr\Log\LoggerInterface;
use function str_starts_with;
@@ -37,56 +38,22 @@ use function str_starts_with;
*
* @package OC\Share20
*/
-class DefaultShareProvider implements IShareProvider {
+class DefaultShareProvider implements IShareProviderWithNotification {
// Special share type for user modified group shares
public const SHARE_TYPE_USERGROUP = 2;
- /** @var IDBConnection */
- private $dbConn;
-
- /** @var IUserManager */
- private $userManager;
-
- /** @var IGroupManager */
- private $groupManager;
-
- /** @var IRootFolder */
- private $rootFolder;
-
- /** @var IMailer */
- private $mailer;
-
- /** @var Defaults */
- private $defaults;
-
- /** @var IFactory */
- private $l10nFactory;
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- private ITimeFactory $timeFactory;
-
public function __construct(
- IDBConnection $connection,
- IUserManager $userManager,
- IGroupManager $groupManager,
- IRootFolder $rootFolder,
- IMailer $mailer,
- Defaults $defaults,
- IFactory $l10nFactory,
- IURLGenerator $urlGenerator,
- ITimeFactory $timeFactory,
+ private IDBConnection $dbConn,
+ private IUserManager $userManager,
+ private IGroupManager $groupManager,
+ private IRootFolder $rootFolder,
+ private IMailer $mailer,
+ private Defaults $defaults,
+ private IFactory $l10nFactory,
+ private IURLGenerator $urlGenerator,
+ private ITimeFactory $timeFactory,
+ private LoggerInterface $logger,
) {
- $this->dbConn = $connection;
- $this->userManager = $userManager;
- $this->groupManager = $groupManager;
- $this->rootFolder = $rootFolder;
- $this->mailer = $mailer;
- $this->defaults = $defaults;
- $this->l10nFactory = $l10nFactory;
- $this->urlGenerator = $urlGenerator;
- $this->timeFactory = $timeFactory;
}
/**
@@ -1200,7 +1167,7 @@ class DefaultShareProvider implements IShareProvider {
);
} else {
$e = new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType);
- \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]);
+ $this->logger->error($e->getMessage(), ['exception' => $e]);
return;
}
@@ -1416,6 +1383,131 @@ class DefaultShareProvider implements IShareProvider {
}
}
+ public function sendMailNotification(IShare $share): bool {
+ try {
+ // Check user
+ $user = $this->userManager->get($share->getSharedWith());
+ if ($user === null) {
+ $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
+ return false;
+ }
+
+ // Handle user shares
+ if ($share->getShareType() === IShare::TYPE_USER) {
+ // Check email address
+ $emailAddress = $user->getEMailAddress();
+ if ($emailAddress === null || $emailAddress === '') {
+ $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
+ return false;
+ }
+
+ $userLang = $this->l10nFactory->getUserLanguage($user);
+ $l = $this->l10nFactory->get('lib', $userLang);
+ $this->sendUserShareMail(
+ $l,
+ $share->getNode()->getName(),
+ $this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
+ $share->getSharedBy(),
+ $emailAddress,
+ $share->getExpirationDate(),
+ $share->getNote()
+ );
+ $this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId() . '.', ['app' => 'share']);
+ return true;
+ }
+ } catch (\Exception $e) {
+ $this->logger->error('Share notification mail could not be sent.', ['exception' => $e]);
+ }
+
+ return false;
+ }
+
+ /**
+ * Send mail notifications for the user share type
+ *
+ * @param IL10N $l Language of the recipient
+ * @param string $filename file/folder name
+ * @param string $link link to the file/folder
+ * @param string $initiator user ID of share sender
+ * @param string $shareWith email address of share receiver
+ * @param \DateTime|null $expiration
+ * @param string $note
+ * @throws \Exception
+ */
+ protected function sendUserShareMail(
+ IL10N $l,
+ $filename,
+ $link,
+ $initiator,
+ $shareWith,
+ ?\DateTime $expiration = null,
+ $note = '') {
+ $initiatorUser = $this->userManager->get($initiator);
+ $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
+
+ $message = $this->mailer->createMessage();
+
+ $emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
+ 'filename' => $filename,
+ 'link' => $link,
+ 'initiator' => $initiatorDisplayName,
+ 'expiration' => $expiration,
+ 'shareWith' => $shareWith,
+ ]);
+
+ $emailTemplate->setSubject($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
+ $emailTemplate->addHeader();
+ $emailTemplate->addHeading($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
+ $text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
+
+ if ($note !== '') {
+ $emailTemplate->addBodyText(htmlspecialchars($note), $note);
+ }
+
+ $emailTemplate->addBodyText(
+ htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
+ $text
+ );
+ $emailTemplate->addBodyButton(
+ $l->t('Open »%s«', [$filename]),
+ $link
+ );
+
+ $message->setTo([$shareWith]);
+
+ // The "From" contains the sharers name
+ $instanceName = $this->defaults->getName();
+ $senderName = $l->t(
+ '%1$s via %2$s',
+ [
+ $initiatorDisplayName,
+ $instanceName,
+ ]
+ );
+ $message->setFrom([\OCP\Util::getDefaultEmailAddress('noreply') => $senderName]);
+
+ // The "Reply-To" is set to the sharer if an mail address is configured
+ // also the default footer contains a "Do not reply" which needs to be adjusted.
+ if ($initiatorUser) {
+ $initiatorEmail = $initiatorUser->getEMailAddress();
+ if ($initiatorEmail !== null) {
+ $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
+ $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
+ } else {
+ $emailTemplate->addFooter();
+ }
+ } else {
+ $emailTemplate->addFooter();
+ }
+
+ $message->useTemplate($emailTemplate);
+ $failedRecipients = $this->mailer->send($message);
+ if (!empty($failedRecipients)) {
+ $this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
+ return;
+ }
+ }
+
/**
* send note by mail
*
@@ -1529,7 +1621,7 @@ class DefaultShareProvider implements IShareProvider {
*
* @return IShare the modified share
*/
- private function updateShareAttributes(IShare $share, ?string $data): IShare {
+ protected function updateShareAttributes(IShare $share, ?string $data): IShare {
if ($data !== null && $data !== '') {
$attributes = new ShareAttributes();
$compressedAttributes = \json_decode($data, true);
@@ -1552,7 +1644,7 @@ class DefaultShareProvider implements IShareProvider {
/**
* Format IAttributes to database format (JSON string)
*/
- private function formatShareAttributes(?IAttributes $attributes): ?string {
+ protected function formatShareAttributes(?IAttributes $attributes): ?string {
if ($attributes === null || empty($attributes->toArray())) {
return null;
}
@@ -1562,7 +1654,7 @@ class DefaultShareProvider implements IShareProvider {
$compressedAttributes[] = [
0 => $attribute['scope'],
1 => $attribute['key'],
- 2 => $attribute['enabled']
+ 2 => $attribute['value']
];
}
return \json_encode($compressedAttributes);
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 7879c137db2..db129709cda 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -44,6 +44,7 @@ use OCP\Share\IManager;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
+use OCP\Share\IShareProviderWithNotification;
use Psr\Log\LoggerInterface;
/**
@@ -655,7 +656,7 @@ class Manager implements IManager {
// Verify the expiration date
$share = $this->validateExpirationDateInternal($share);
} elseif ($share->getShareType() === IShare::TYPE_REMOTE || $share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
- //Verify the expiration date
+ // Verify the expiration date
$share = $this->validateExpirationDateInternal($share);
} elseif ($share->getShareType() === IShare::TYPE_LINK
|| $share->getShareType() === IShare::TYPE_EMAIL) {
@@ -732,123 +733,23 @@ class Manager implements IManager {
// Post share event
$this->dispatcher->dispatchTyped(new ShareCreatedEvent($share));
- if ($this->config->getSystemValueBool('sharing.enable_share_mail', true)
- && $share->getShareType() === IShare::TYPE_USER) {
- $mailSend = $share->getMailSend();
- if ($mailSend === true) {
- $user = $this->userManager->get($share->getSharedWith());
- if ($user !== null) {
- $emailAddress = $user->getEMailAddress();
- if ($emailAddress !== null && $emailAddress !== '') {
- $userLang = $this->l10nFactory->getUserLanguage($user);
- $l = $this->l10nFactory->get('lib', $userLang);
- $this->sendMailNotification(
- $l,
- $share->getNode()->getName(),
- $this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
- $share->getSharedBy(),
- $emailAddress,
- $share->getExpirationDate(),
- $share->getNote()
- );
- $this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
- } else {
- $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
- }
+ // Send email if needed
+ if ($this->config->getSystemValueBool('sharing.enable_share_mail', true)) {
+ if ($share->getMailSend()) {
+ $provider = $this->factory->getProviderForType($share->getShareType());
+ if ($provider instanceof IShareProviderWithNotification) {
+ $provider->sendMailNotification($share);
} else {
- $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
+ $this->logger->debug('Share notification not sent because the provider does not support it.', ['app' => 'share']);
}
} else {
$this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
}
- }
-
- return $share;
- }
-
- /**
- * Send mail notifications
- *
- * This method will catch and log mail transmission errors
- *
- * @param IL10N $l Language of the recipient
- * @param string $filename file/folder name
- * @param string $link link to the file/folder
- * @param string $initiator user ID of share sender
- * @param string $shareWith email address of share receiver
- * @param \DateTime|null $expiration
- */
- protected function sendMailNotification(IL10N $l,
- $filename,
- $link,
- $initiator,
- $shareWith,
- ?\DateTime $expiration = null,
- $note = '') {
- $initiatorUser = $this->userManager->get($initiator);
- $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
-
- $message = $this->mailer->createMessage();
-
- $emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
- 'filename' => $filename,
- 'link' => $link,
- 'initiator' => $initiatorDisplayName,
- 'expiration' => $expiration,
- 'shareWith' => $shareWith,
- ]);
-
- $emailTemplate->setSubject($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
- $emailTemplate->addHeader();
- $emailTemplate->addHeading($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
- $text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
-
- if ($note !== '') {
- $emailTemplate->addBodyText(htmlspecialchars($note), $note);
- }
-
- $emailTemplate->addBodyText(
- htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
- $text
- );
- $emailTemplate->addBodyButton(
- $l->t('Open »%s«', [$filename]),
- $link
- );
-
- $message->setTo([$shareWith]);
-
- // The "From" contains the sharers name
- $instanceName = $this->defaults->getName();
- $senderName = $l->t(
- '%1$s via %2$s',
- [
- $initiatorDisplayName,
- $instanceName,
- ]
- );
- $message->setFrom([\OCP\Util::getDefaultEmailAddress('noreply') => $senderName]);
-
- // The "Reply-To" is set to the sharer if an mail address is configured
- // also the default footer contains a "Do not reply" which needs to be adjusted.
- $initiatorEmail = $initiatorUser->getEMailAddress();
- if ($initiatorEmail !== null) {
- $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
- $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
} else {
- $emailTemplate->addFooter('', $l->getLanguageCode());
+ $this->logger->debug('Share notification not sent because sharing notification emails is disabled.', ['app' => 'share']);
}
- $message->useTemplate($emailTemplate);
- try {
- $failedRecipients = $this->mailer->send($message);
- if (!empty($failedRecipients)) {
- $this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
- return;
- }
- } catch (\Exception $e) {
- $this->logger->error('Share notification mail could not be sent', ['exception' => $e]);
- }
+ return $share;
}
/**
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 9716d1e7556..dbe251a49df 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -87,6 +87,7 @@ class ProviderFactory implements IProviderFactory {
$this->serverContainer->get(IFactory::class),
$this->serverContainer->getURLGenerator(),
$this->serverContainer->query(ITimeFactory::class),
+ $this->serverContainer->get(LoggerInterface::class),
);
}
diff --git a/lib/private/Share20/ShareAttributes.php b/lib/private/Share20/ShareAttributes.php
index abbbd36759b..fbdcbf1ad26 100644
--- a/lib/private/Share20/ShareAttributes.php
+++ b/lib/private/Share20/ShareAttributes.php
@@ -20,18 +20,18 @@ class ShareAttributes implements IAttributes {
/**
* @inheritdoc
*/
- public function setAttribute($scope, $key, $enabled) {
+ public function setAttribute(string $scope, string $key, mixed $value): IAttributes {
if (!\array_key_exists($scope, $this->attributes)) {
$this->attributes[$scope] = [];
}
- $this->attributes[$scope][$key] = $enabled;
+ $this->attributes[$scope][$key] = $value;
return $this;
}
/**
* @inheritdoc
*/
- public function getAttribute($scope, $key) {
+ public function getAttribute(string $scope, string $key): mixed {
if (\array_key_exists($scope, $this->attributes) &&
\array_key_exists($key, $this->attributes[$scope])) {
return $this->attributes[$scope][$key];
@@ -42,14 +42,14 @@ class ShareAttributes implements IAttributes {
/**
* @inheritdoc
*/
- public function toArray() {
+ public function toArray(): array {
$result = [];
foreach ($this->attributes as $scope => $keys) {
- foreach ($keys as $key => $enabled) {
+ foreach ($keys as $key => $value) {
$result[] = [
"scope" => $scope,
"key" => $key,
- "enabled" => $enabled
+ "value" => $value,
];
}
}
diff --git a/lib/public/AppFramework/Http/Attribute/ARateLimit.php b/lib/public/AppFramework/Http/Attribute/ARateLimit.php
index d92fcae1ae1..c06b1180ae3 100644
--- a/lib/public/AppFramework/Http/Attribute/ARateLimit.php
+++ b/lib/public/AppFramework/Http/Attribute/ARateLimit.php
@@ -17,6 +17,8 @@ namespace OCP\AppFramework\Http\Attribute;
*/
abstract class ARateLimit {
/**
+ * @param int $limit The maximum number of requests that can be made in the given period in seconds.
+ * @param int $period The time period in seconds.
* @since 27.0.0
*/
public function __construct(
diff --git a/lib/public/Share/IAttributes.php b/lib/public/Share/IAttributes.php
index af7277c39c0..fad19c60aad 100644
--- a/lib/public/Share/IAttributes.php
+++ b/lib/public/Share/IAttributes.php
@@ -13,26 +13,26 @@ namespace OCP\Share;
*/
interface IAttributes {
/**
- * Sets an attribute enabled/disabled. If the key did not exist before it will be created.
+ * Sets an attribute. If the key did not exist before it will be created.
*
* @param string $scope scope
* @param string $key key
- * @param bool $enabled enabled
+ * @param bool|string|array|null $value value
* @return IAttributes The modified object
* @since 25.0.0
*/
- public function setAttribute($scope, $key, $enabled);
+ public function setAttribute(string $scope, string $key, mixed $value): IAttributes;
/**
- * Returns if attribute is enabled/disabled for given scope id and key.
+ * Returns the attribute for given scope id and key.
* If attribute does not exist, returns null
*
* @param string $scope scope
* @param string $key key
- * @return bool|null
+ * @return bool|string|array|null
* @since 25.0.0
*/
- public function getAttribute($scope, $key);
+ public function getAttribute(string $scope, string $key): mixed;
/**
* Formats the IAttributes object to array with the following format:
@@ -40,13 +40,14 @@ interface IAttributes {
* 0 => [
* "scope" => <string>,
* "key" => <string>,
- * "enabled" => <bool>
+ * "value" => <bool|string|array|null>,
* ],
* ...
* ]
*
* @return array formatted IAttributes
* @since 25.0.0
+ * @since 30.0.0, `enabled` was renamed to `value`
*/
- public function toArray();
+ public function toArray(): array;
}
diff --git a/lib/public/Share/IManager.php b/lib/public/Share/IManager.php
index 063e776e68a..b07bc8f8051 100644
--- a/lib/public/Share/IManager.php
+++ b/lib/public/Share/IManager.php
@@ -300,7 +300,7 @@ interface IManager {
public function shareApiAllowLinks();
/**
- * Is password on public link requires
+ * Is password on public link required
*
* @param bool $checkGroupMembership Check group membership exclusion
* @return bool
diff --git a/lib/public/Share/IShare.php b/lib/public/Share/IShare.php
index 91eebd3afa9..fe5e7eb47dd 100644
--- a/lib/public/Share/IShare.php
+++ b/lib/public/Share/IShare.php
@@ -564,7 +564,7 @@ interface IShare {
public function getShareTime();
/**
- * Set if the recipient is informed by mail about the share.
+ * Set if the recipient should be informed by mail about the share.
*
* @param bool $mailSend
* @return \OCP\Share\IShare The modified object
@@ -573,7 +573,7 @@ interface IShare {
public function setMailSend($mailSend);
/**
- * Get if the recipient informed by mail about the share.
+ * Get if the recipient should be informed by mail about the share.
*
* @return bool
* @since 9.0.0
diff --git a/lib/public/Share/IShareProviderWithNotification.php b/lib/public/Share/IShareProviderWithNotification.php
new file mode 100644
index 00000000000..afd1429c1f0
--- /dev/null
+++ b/lib/public/Share/IShareProviderWithNotification.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCP\Share;
+
+/**
+ * Interface IShareProvider
+ *
+ * @since 30.0.0
+ */
+interface IShareProviderWithNotification extends IShareProvider {
+ /**
+ * Send a mail notification to the recipient of a share
+ * @param IShare $share
+ * @return bool True if the mail was sent successfully
+ * @throws \Exception If the mail could not be sent
+ * @since 30.0.0
+ */
+ public function sendMailNotification(IShare $share): bool;
+}