mirror of
https://github.com/nextcloud/server.git
synced 2024-07-29 20:15:55 +02:00
Merge pull request #1800 from nextcloud/nextcloud-rich-object-strings
Nextcloud rich object strings
This commit is contained in:
commit
d4969abc9d
@ -32,7 +32,8 @@ $app->registerSettings();
|
||||
$manager = \OC::$server->getNotificationManager();
|
||||
$manager->registerNotifier(function() {
|
||||
return new Notifier(
|
||||
\OC::$server->getL10NFactory()
|
||||
\OC::$server->getL10NFactory(),
|
||||
\OC::$server->getContactsManager()
|
||||
);
|
||||
}, function() use ($l) {
|
||||
return [
|
||||
|
@ -24,18 +24,28 @@
|
||||
namespace OCA\FederatedFileSharing;
|
||||
|
||||
|
||||
use OC\HintException;
|
||||
use OC\Share\Helper;
|
||||
use OCP\Contacts\IManager;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\Notification\INotifier;
|
||||
|
||||
class Notifier implements INotifier {
|
||||
/** @var \OCP\L10N\IFactory */
|
||||
/** @var IFactory */
|
||||
protected $factory;
|
||||
/** @var IManager */
|
||||
protected $contactsManager;
|
||||
/** @var array */
|
||||
protected $federatedContacts;
|
||||
|
||||
/**
|
||||
* @param \OCP\L10N\IFactory $factory
|
||||
* @param IFactory $factory
|
||||
* @param IManager $contactsManager
|
||||
*/
|
||||
public function __construct(\OCP\L10N\IFactory $factory) {
|
||||
public function __construct(IFactory $factory, IManager $contactsManager) {
|
||||
$this->factory = $factory;
|
||||
$this->contactsManager = $contactsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,11 +68,34 @@ class Notifier implements INotifier {
|
||||
$params = $notification->getSubjectParameters();
|
||||
if ($params[0] !== $params[1] && $params[1] !== null) {
|
||||
$notification->setParsedSubject(
|
||||
(string) $l->t('You received "/%3$s" as a remote share from %1$s (on behalf of %2$s)', $params)
|
||||
$l->t('You received "%3$s" as a remote share from %1$s (on behalf of %2$s)', $params)
|
||||
);
|
||||
$notification->setRichSubject(
|
||||
$l->t('You received {share} as a remote share from {user} (on behalf of {behalf})'),
|
||||
[
|
||||
'share' => [
|
||||
'type' => 'pending-federated-share',
|
||||
'id' => $notification->getObjectId(),
|
||||
'name' => $params[2],
|
||||
],
|
||||
'user' => $this->createRemoteUser($params[0]),
|
||||
'behalf' => $this->createRemoteUser($params[1]),
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$notification->setParsedSubject(
|
||||
(string)$l->t('You received "/%3$s" as a remote share from %1$s', $params)
|
||||
$l->t('You received "%3$s" as a remote share from %1$s', $params)
|
||||
);
|
||||
$notification->setRichSubject(
|
||||
$l->t('You received {share} as a remote share from {user}'),
|
||||
[
|
||||
'share' => [
|
||||
'type' => 'pending-federated-share',
|
||||
'id' => $notification->getObjectId(),
|
||||
'name' => $params[2],
|
||||
],
|
||||
'user' => $this->createRemoteUser($params[0]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@ -92,4 +125,93 @@ class Notifier implements INotifier {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cloudId
|
||||
* @return array
|
||||
*/
|
||||
protected function createRemoteUser($cloudId) {
|
||||
$displayName = $cloudId;
|
||||
try {
|
||||
list($user, $server) = Helper::splitUserRemote($cloudId);
|
||||
$displayName = $this->getDisplayName($user, $server);
|
||||
} catch (HintException $e) {
|
||||
$user = $cloudId;
|
||||
$server = '';
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => 'user',
|
||||
'id' => $user,
|
||||
'name' => $displayName,
|
||||
'server' => $server,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find the user in the contacts
|
||||
*
|
||||
* @param string $user
|
||||
* @param string $server
|
||||
* @return string
|
||||
* @throws \OutOfBoundsException when there is no contact for the id
|
||||
*/
|
||||
protected function getDisplayName($user, $server) {
|
||||
$server = strtolower(rtrim($server, '/'));
|
||||
|
||||
if (strpos($server, 'http://') === 0) {
|
||||
$server = substr($server, strlen('http://'));
|
||||
} else if (strpos($server, 'https://') === 0) {
|
||||
$server = substr($server, strlen('https://'));
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->getDisplayNameFromContact($user . '@' . $server);
|
||||
} catch (\OutOfBoundsException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->getDisplayNameFromContact($user . '@http://' . $server);
|
||||
} catch (\OutOfBoundsException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->getDisplayNameFromContact($user . '@https://' . $server);
|
||||
} catch (\OutOfBoundsException $e) {
|
||||
}
|
||||
|
||||
return $user . '@' . $server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find the user in the contacts
|
||||
*
|
||||
* @param string $federatedCloudId
|
||||
* @return string
|
||||
* @throws \OutOfBoundsException when there is no contact for the id
|
||||
*/
|
||||
protected function getDisplayNameFromContact($federatedCloudId) {
|
||||
if (isset($this->federatedContacts[$federatedCloudId])) {
|
||||
if ($this->federatedContacts[$federatedCloudId] !== '') {
|
||||
return $this->federatedContacts[$federatedCloudId];
|
||||
} else {
|
||||
throw new \OutOfBoundsException('No contact found for federated cloud id');
|
||||
}
|
||||
}
|
||||
|
||||
$addressBookEntries = $this->contactsManager->search($federatedCloudId, ['CLOUD']);
|
||||
foreach ($addressBookEntries as $entry) {
|
||||
if (isset($entry['CLOUD'])) {
|
||||
foreach ($entry['CLOUD'] as $cloudID) {
|
||||
if ($cloudID === $federatedCloudId) {
|
||||
$this->federatedContacts[$federatedCloudId] = $entry['FN'];
|
||||
return $entry['FN'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->federatedContacts[$federatedCloudId] = '';
|
||||
throw new \OutOfBoundsException('No contact found for federated cloud id');
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +200,8 @@ return array(
|
||||
'OCP\\PreConditionNotMetException' => $baseDir . '/lib/public/PreConditionNotMetException.php',
|
||||
'OCP\\Preview\\IProvider' => $baseDir . '/lib/public/Preview/IProvider.php',
|
||||
'OCP\\Response' => $baseDir . '/lib/public/Response.php',
|
||||
'OCP\\RichObjectStrings\\IValidator' => $baseDir . '/lib/public/RichObjectStrings/IValidator.php',
|
||||
'OCP\\RichObjectStrings\\InvalidObjectExeption' => $baseDir . '/lib/public/RichObjectStrings/InvalidObjectExeption.php',
|
||||
'OCP\\Route\\IRoute' => $baseDir . '/lib/public/Route/IRoute.php',
|
||||
'OCP\\Route\\IRouter' => $baseDir . '/lib/public/Route/IRouter.php',
|
||||
'OCP\\SabrePluginEvent' => $baseDir . '/lib/public/SabrePluginEvent.php',
|
||||
@ -663,6 +665,7 @@ return array(
|
||||
'OC\\Repair\\SqliteAutoincrement' => $baseDir . '/lib/private/Repair/SqliteAutoincrement.php',
|
||||
'OC\\Repair\\UpdateCertificateStore' => $baseDir . '/lib/private/Repair/UpdateCertificateStore.php',
|
||||
'OC\\Repair\\UpdateOutdatedOcsIds' => $baseDir . '/lib/private/Repair/UpdateOutdatedOcsIds.php',
|
||||
'OC\\RichObjectStrings\\Validator' => $baseDir . '/lib/private/RichObjectStrings/Validator.php',
|
||||
'OC\\Route\\CachingRouter' => $baseDir . '/lib/private/Route/CachingRouter.php',
|
||||
'OC\\Route\\Route' => $baseDir . '/lib/private/Route/Route.php',
|
||||
'OC\\Route\\Router' => $baseDir . '/lib/private/Route/Router.php',
|
||||
|
@ -230,6 +230,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||
'OCP\\PreConditionNotMetException' => __DIR__ . '/../../..' . '/lib/public/PreConditionNotMetException.php',
|
||||
'OCP\\Preview\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Preview/IProvider.php',
|
||||
'OCP\\Response' => __DIR__ . '/../../..' . '/lib/public/Response.php',
|
||||
'OCP\\RichObjectStrings\\IValidator' => __DIR__ . '/../../..' . '/lib/public/RichObjectStrings/IValidator.php',
|
||||
'OCP\\RichObjectStrings\\InvalidObjectExeption' => __DIR__ . '/../../..' . '/lib/public/RichObjectStrings/InvalidObjectExeption.php',
|
||||
'OCP\\Route\\IRoute' => __DIR__ . '/../../..' . '/lib/public/Route/IRoute.php',
|
||||
'OCP\\Route\\IRouter' => __DIR__ . '/../../..' . '/lib/public/Route/IRouter.php',
|
||||
'OCP\\SabrePluginEvent' => __DIR__ . '/../../..' . '/lib/public/SabrePluginEvent.php',
|
||||
@ -693,6 +695,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||
'OC\\Repair\\SqliteAutoincrement' => __DIR__ . '/../../..' . '/lib/private/Repair/SqliteAutoincrement.php',
|
||||
'OC\\Repair\\UpdateCertificateStore' => __DIR__ . '/../../..' . '/lib/private/Repair/UpdateCertificateStore.php',
|
||||
'OC\\Repair\\UpdateOutdatedOcsIds' => __DIR__ . '/../../..' . '/lib/private/Repair/UpdateOutdatedOcsIds.php',
|
||||
'OC\\RichObjectStrings\\Validator' => __DIR__ . '/../../..' . '/lib/private/RichObjectStrings/Validator.php',
|
||||
'OC\\Route\\CachingRouter' => __DIR__ . '/../../..' . '/lib/private/Route/CachingRouter.php',
|
||||
'OC\\Route\\Route' => __DIR__ . '/../../..' . '/lib/private/Route/Route.php',
|
||||
'OC\\Route\\Router' => __DIR__ . '/../../..' . '/lib/private/Route/Router.php',
|
||||
|
@ -44,10 +44,12 @@ use OC\AppFramework\Middleware\Security\SecurityMiddleware;
|
||||
use OC\AppFramework\Middleware\SessionMiddleware;
|
||||
use OC\AppFramework\Utility\SimpleContainer;
|
||||
use OC\Core\Middleware\TwoFactorMiddleware;
|
||||
use OC\RichObjectStrings\Validator;
|
||||
use OCP\AppFramework\IApi;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use OCP\RichObjectStrings\IValidator;
|
||||
|
||||
class DIContainer extends SimpleContainer implements IAppContainer {
|
||||
|
||||
@ -330,6 +332,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
||||
return $this->getServer()->getEncryptionManager();
|
||||
});
|
||||
|
||||
$this->registerService(IValidator::class, function($c) {
|
||||
return $c->query(Validator::class);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* App Framework APIs
|
||||
|
@ -24,6 +24,7 @@
|
||||
namespace OC\Notification;
|
||||
|
||||
|
||||
use OC\RichObjectStrings\Validator;
|
||||
use OCP\Notification\IApp;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
@ -149,7 +150,9 @@ class Manager implements IManager {
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function createNotification() {
|
||||
return new Notification();
|
||||
return new Notification(
|
||||
new Validator()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,8 +26,14 @@ namespace OC\Notification;
|
||||
|
||||
use OCP\Notification\IAction;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\RichObjectStrings\InvalidObjectExeption;
|
||||
use OCP\RichObjectStrings\IValidator;
|
||||
|
||||
class Notification implements INotification {
|
||||
|
||||
/** @var IValidator */
|
||||
protected $richValidator;
|
||||
|
||||
/** @var string */
|
||||
protected $app;
|
||||
|
||||
@ -52,6 +58,12 @@ class Notification implements INotification {
|
||||
/** @var string */
|
||||
protected $subjectParsed;
|
||||
|
||||
/** @var string */
|
||||
protected $subjectRich;
|
||||
|
||||
/** @var array */
|
||||
protected $subjectRichParameters;
|
||||
|
||||
/** @var string */
|
||||
protected $message;
|
||||
|
||||
@ -81,8 +93,11 @@ class Notification implements INotification {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param IValidator $richValidator
|
||||
*/
|
||||
public function __construct() {
|
||||
public function __construct(IValidator $richValidator) {
|
||||
$this->richValidator = $richValidator;
|
||||
$this->app = '';
|
||||
$this->user = '';
|
||||
$this->dateTime = new \DateTime();
|
||||
@ -92,6 +107,8 @@ class Notification implements INotification {
|
||||
$this->subject = '';
|
||||
$this->subjectParameters = [];
|
||||
$this->subjectParsed = '';
|
||||
$this->subjectRich = '';
|
||||
$this->subjectRichParameters = [];
|
||||
$this->message = '';
|
||||
$this->messageParameters = [];
|
||||
$this->messageParsed = '';
|
||||
@ -261,6 +278,43 @@ class Notification implements INotification {
|
||||
return $this->subjectParsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param array $parameters
|
||||
* @return $this
|
||||
* @throws \InvalidArgumentException if the subject or parameters are invalid
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function setRichSubject($subject, array $parameters = []) {
|
||||
if (!is_string($subject) || $subject === '') {
|
||||
throw new \InvalidArgumentException('The given parsed subject is invalid');
|
||||
}
|
||||
$this->subjectRich = $subject;
|
||||
|
||||
if (!is_array($parameters)) {
|
||||
throw new \InvalidArgumentException('The given subject parameters are invalid');
|
||||
}
|
||||
$this->subjectRichParameters = $parameters;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function getRichSubject() {
|
||||
return $this->subjectRich;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function getRichSubjectParameters() {
|
||||
return $this->subjectRichParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $parameters
|
||||
@ -454,6 +508,14 @@ class Notification implements INotification {
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function isValidParsed() {
|
||||
if ($this->getRichSubject() !== '' || !empty($this->getRichSubjectParameters())) {
|
||||
try {
|
||||
$this->richValidator->validate($this->getRichSubject(), $this->getRichSubjectParameters());
|
||||
} catch (InvalidObjectExeption $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
$this->isValidCommon()
|
||||
&&
|
||||
|
108
lib/private/RichObjectStrings/Validator.php
Normal file
108
lib/private/RichObjectStrings/Validator.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\RichObjectStrings;
|
||||
|
||||
|
||||
use OCP\RichObjectStrings\InvalidObjectExeption;
|
||||
use OCP\RichObjectStrings\IValidator;
|
||||
|
||||
/**
|
||||
* Class Validator
|
||||
*
|
||||
* @package OCP\RichObjectStrings
|
||||
* @since 9.2.0
|
||||
*/
|
||||
class Validator implements IValidator {
|
||||
|
||||
/** @var array[] */
|
||||
protected $definitions;
|
||||
|
||||
/** @var array[] */
|
||||
protected $requiredParameters = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->definitions = json_decode(file_get_contents(__DIR__ . '/../../public/RichObjectStrings/definitions.json'), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param array[] $parameters
|
||||
* @throws InvalidObjectExeption
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function validate($subject, array $parameters) {
|
||||
$matches = [];
|
||||
$result = preg_match_all('/\{([a-z0-9]+)\}/i', $subject, $matches);
|
||||
|
||||
if ($result === false) {
|
||||
throw new InvalidObjectExeption();
|
||||
}
|
||||
|
||||
if (!empty($matches[1])) {
|
||||
foreach ($matches[1] as $parameter) {
|
||||
if (!isset($parameters[$parameter])) {
|
||||
throw new InvalidObjectExeption('Parameter is undefined');
|
||||
} else {
|
||||
$this->validateParameter($parameters[$parameter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameter
|
||||
* @throws InvalidObjectExeption
|
||||
*/
|
||||
protected function validateParameter(array $parameter) {
|
||||
if (!isset($parameter['type']) || !isset($this->definitions[$parameter['type']])) {
|
||||
throw new InvalidObjectExeption('Object type is undefined');
|
||||
}
|
||||
|
||||
$requiredParameters = $this->getRequiredParameters($parameter['type']);
|
||||
$missingKeys = array_diff($requiredParameters, array_keys($parameter));
|
||||
if (!empty($missingKeys)) {
|
||||
throw new InvalidObjectExeption('Object is invalid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getRequiredParameters($type) {
|
||||
if (isset($this->requiredParameters[$type])) {
|
||||
return $this->requiredParameters[$type];
|
||||
}
|
||||
|
||||
$this->requiredParameters[$type] = [];
|
||||
foreach ($this->definitions[$type]['parameters'] as $parameter => $data) {
|
||||
if ($data['required']) {
|
||||
$this->requiredParameters[$type][] = $parameter;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->requiredParameters[$type];
|
||||
}
|
||||
}
|
@ -127,6 +127,27 @@ interface INotification {
|
||||
*/
|
||||
public function getParsedSubject();
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param array $parameters
|
||||
* @return $this
|
||||
* @throws \InvalidArgumentException if the subject or parameters are invalid
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function setRichSubject($subject, array $parameters = []);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function getRichSubject();
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function getRichSubjectParameters();
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $parameters
|
||||
|
39
lib/public/RichObjectStrings/IValidator.php
Normal file
39
lib/public/RichObjectStrings/IValidator.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCP\RichObjectStrings;
|
||||
|
||||
/**
|
||||
* Class Validator
|
||||
*
|
||||
* @package OCP\RichObjectStrings
|
||||
* @since 9.2.0
|
||||
*/
|
||||
interface IValidator {
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param array[] $parameters
|
||||
* @throws InvalidObjectExeption
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function validate($subject, array $parameters);
|
||||
}
|
31
lib/public/RichObjectStrings/InvalidObjectExeption.php
Normal file
31
lib/public/RichObjectStrings/InvalidObjectExeption.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCP\RichObjectStrings;
|
||||
|
||||
/**
|
||||
* Class InvalidObjectExeption
|
||||
*
|
||||
* @package OCP\RichObjectStrings
|
||||
* @since 9.2.0
|
||||
*/
|
||||
class InvalidObjectExeption extends \InvalidArgumentException {
|
||||
}
|
228
lib/public/RichObjectStrings/definitions.json
Normal file
228
lib/public/RichObjectStrings/definitions.json
Normal file
@ -0,0 +1,228 @@
|
||||
{
|
||||
"addressbook": {
|
||||
"author": "Nextcloud",
|
||||
"app": "dav",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the addressbook on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the addressbook which should be used in the visual representation",
|
||||
"example": "Contacts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"addressbook-contact": {
|
||||
"author": "Nextcloud",
|
||||
"app": "dav",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the contact on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the contact which should be used in the visual representation",
|
||||
"example": "John Doe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"announcement": {
|
||||
"author": "Joas Schilling",
|
||||
"app": "announcementcenter",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the announcement on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The announcement subject which should be used in the visual representation",
|
||||
"example": "file.txt"
|
||||
},
|
||||
"link": {
|
||||
"since": "9.2.0",
|
||||
"required": false,
|
||||
"description": "The full URL to the file",
|
||||
"example": "http://localhost/index.php/apps/announcements/#23"
|
||||
}
|
||||
}
|
||||
},
|
||||
"calendar": {
|
||||
"author": "Nextcloud",
|
||||
"app": "dav",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the calendar on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the calendar which should be used in the visual representation",
|
||||
"example": "Personal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"calendar-event": {
|
||||
"author": "Nextcloud",
|
||||
"app": "dav",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the event on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the event which should be used in the visual representation",
|
||||
"example": "Workout"
|
||||
}
|
||||
}
|
||||
},
|
||||
"file": {
|
||||
"author": "Nextcloud",
|
||||
"app": "dav",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the file on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The file name which should be used in the visual representation",
|
||||
"example": "file.txt"
|
||||
},
|
||||
"path": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The full path of the file for the user",
|
||||
"example": "path/to/file.txt"
|
||||
},
|
||||
"link": {
|
||||
"since": "9.2.0",
|
||||
"required": false,
|
||||
"description": "The full URL to the file",
|
||||
"example": "http://localhost/index.php/f/42"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pending-federated-share": {
|
||||
"author": "Nextcloud",
|
||||
"app": "dav",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the federated share on the instance",
|
||||
"example": "42"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The name of the shared item which should be used in the visual representation",
|
||||
"example": "file.txt"
|
||||
}
|
||||
}
|
||||
},
|
||||
"systemtag": {
|
||||
"author": "Nextcloud",
|
||||
"app": "core",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the systemtag on the instance",
|
||||
"example": "23"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the systemtag which should be used in the visual representation",
|
||||
"example": "Project 1"
|
||||
},
|
||||
"visibility": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "If the user can see the systemtag",
|
||||
"example": "1"
|
||||
},
|
||||
"assignable": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "If the user can assign the systemtag",
|
||||
"example": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"author": "Nextcloud",
|
||||
"app": "core",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the user on the instance",
|
||||
"example": "johndoe"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the user which should be used in the visual representation",
|
||||
"example": "John Doe"
|
||||
},
|
||||
"server": {
|
||||
"since": "9.2.0",
|
||||
"required": false,
|
||||
"description": "The URL of the instance the user lives on",
|
||||
"example": "localhost"
|
||||
}
|
||||
}
|
||||
},
|
||||
"user-group": {
|
||||
"author": "Nextcloud",
|
||||
"app": "core",
|
||||
"since": "9.2.0",
|
||||
"parameters": {
|
||||
"id": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The id used to identify the group on the instance",
|
||||
"example": "supportteam"
|
||||
},
|
||||
"name": {
|
||||
"since": "9.2.0",
|
||||
"required": true,
|
||||
"description": "The display name of the group which should be used in the visual representation",
|
||||
"example": "Support Team"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -23,16 +23,21 @@ namespace Test\Notification;
|
||||
|
||||
|
||||
use OC\Notification\Notification;
|
||||
use OCP\Notification\IAction;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\RichObjectStrings\IValidator;
|
||||
use Test\TestCase;
|
||||
|
||||
class NotificationTest extends TestCase {
|
||||
/** @var INotification */
|
||||
protected $notification;
|
||||
/** @var IValidator|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $validator;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->notification = new Notification();
|
||||
$this->validator = $this->createMock(IValidator::class);
|
||||
$this->notification = new Notification($this->validator);
|
||||
}
|
||||
|
||||
protected function dataValidString($maxLength) {
|
||||
@ -416,14 +421,12 @@ class NotificationTest extends TestCase {
|
||||
|
||||
public function testCreateAction() {
|
||||
$action = $this->notification->createAction();
|
||||
$this->assertInstanceOf('OCP\Notification\IAction', $action);
|
||||
$this->assertInstanceOf(IAction::class, $action);
|
||||
}
|
||||
|
||||
public function testAddAction() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action = $this->createMock(IAction::class);
|
||||
$action->expects($this->once())
|
||||
->method('isValid')
|
||||
->willReturn(true);
|
||||
@ -441,9 +444,7 @@ class NotificationTest extends TestCase {
|
||||
*/
|
||||
public function testAddActionInvalid() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action = $this->createMock(IAction::class);
|
||||
$action->expects($this->once())
|
||||
->method('isValid')
|
||||
->willReturn(false);
|
||||
@ -455,9 +456,7 @@ class NotificationTest extends TestCase {
|
||||
|
||||
public function testAddActionSecondPrimary() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action = $this->createMock(IAction::class);
|
||||
$action->expects($this->exactly(2))
|
||||
->method('isValid')
|
||||
->willReturn(true);
|
||||
@ -473,9 +472,7 @@ class NotificationTest extends TestCase {
|
||||
|
||||
public function testAddParsedAction() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action = $this->createMock(IAction::class);
|
||||
$action->expects($this->once())
|
||||
->method('isValidParsed')
|
||||
->willReturn(true);
|
||||
@ -493,9 +490,7 @@ class NotificationTest extends TestCase {
|
||||
*/
|
||||
public function testAddParsedActionInvalid() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action = $this->createMock(IAction::class);
|
||||
$action->expects($this->once())
|
||||
->method('isValidParsed')
|
||||
->willReturn(false);
|
||||
@ -507,9 +502,7 @@ class NotificationTest extends TestCase {
|
||||
|
||||
public function testAddActionSecondParsedPrimary() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action = $this->createMock(IAction::class);
|
||||
$action->expects($this->exactly(2))
|
||||
->method('isValidParsed')
|
||||
->willReturn(true);
|
||||
@ -525,9 +518,7 @@ class NotificationTest extends TestCase {
|
||||
|
||||
public function testAddActionParsedPrimaryEnd() {
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action1 = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action1 = $this->createMock(IAction::class);
|
||||
$action1->expects($this->exactly(2))
|
||||
->method('isValidParsed')
|
||||
->willReturn(true);
|
||||
@ -535,9 +526,7 @@ class NotificationTest extends TestCase {
|
||||
->method('isPrimary')
|
||||
->willReturn(false);
|
||||
/** @var \OCP\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
|
||||
$action2 = $this->getMockBuilder('OCP\Notification\IAction')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$action2 = $this->createMock(IAction::class);
|
||||
$action2->expects($this->once())
|
||||
->method('isValidParsed')
|
||||
->willReturn(true);
|
||||
@ -570,12 +559,13 @@ class NotificationTest extends TestCase {
|
||||
*/
|
||||
public function testIsValid($isValidCommon, $subject, $expected) {
|
||||
/** @var \OCP\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->getMockBuilder('\OC\Notification\Notification')
|
||||
$notification = $this->getMockBuilder(Notification::class)
|
||||
->setMethods([
|
||||
'isValidCommon',
|
||||
'getSubject',
|
||||
'getParsedSubject',
|
||||
])
|
||||
->setConstructorArgs([$this->validator])
|
||||
->getMock();
|
||||
|
||||
$notification->expects($this->once())
|
||||
@ -602,12 +592,13 @@ class NotificationTest extends TestCase {
|
||||
*/
|
||||
public function testIsParsedValid($isValidCommon, $subject, $expected) {
|
||||
/** @var \OCP\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->getMockBuilder('\OC\Notification\Notification')
|
||||
$notification = $this->getMockBuilder(Notification::class)
|
||||
->setMethods([
|
||||
'isValidCommon',
|
||||
'getParsedSubject',
|
||||
'getSubject',
|
||||
])
|
||||
->setConstructorArgs([$this->validator])
|
||||
->getMock();
|
||||
|
||||
$notification->expects($this->once())
|
||||
@ -648,7 +639,7 @@ class NotificationTest extends TestCase {
|
||||
*/
|
||||
public function testIsValidCommon($app, $user, $timestamp, $objectType, $objectId, $expected) {
|
||||
/** @var \OCP\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->getMockBuilder('\OC\Notification\Notification')
|
||||
$notification = $this->getMockBuilder(Notification::class)
|
||||
->setMethods([
|
||||
'getApp',
|
||||
'getUser',
|
||||
@ -656,6 +647,7 @@ class NotificationTest extends TestCase {
|
||||
'getObjectType',
|
||||
'getObjectId',
|
||||
])
|
||||
->setConstructorArgs([$this->validator])
|
||||
->getMock();
|
||||
|
||||
$notification->expects($this->any())
|
||||
|
53
tests/lib/RichObjectStrings/ValidatorTest.php
Normal file
53
tests/lib/RichObjectStrings/ValidatorTest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Test\RichObjectStrings;
|
||||
|
||||
|
||||
use OC\RichObjectStrings\Validator;
|
||||
use Test\TestCase;
|
||||
|
||||
class ValidatorTest extends TestCase {
|
||||
|
||||
public function test() {
|
||||
$v = new Validator();
|
||||
$v->validate('test', []);
|
||||
$v->validate('test {string1} test {foo} test {bar}.', [
|
||||
'string1' => [
|
||||
'type' => 'user',
|
||||
'id' => 'johndoe',
|
||||
'name' => 'John Doe',
|
||||
],
|
||||
'foo' => [
|
||||
'type' => 'user-group',
|
||||
'id' => 'sample',
|
||||
'name' => 'Sample Group',
|
||||
],
|
||||
'bar' => [
|
||||
'type' => 'file',
|
||||
'id' => '42',
|
||||
'name' => 'test.txt',
|
||||
'path' => 'path/to/test.txt',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user