Signed-off-by: Joas Schilling <coding@schilljs.com>tags/v11.0RC2
@@ -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 |
@@ -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]; | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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 { | |||
} |
@@ -0,0 +1,209 @@ | |||
{ | |||
"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" | |||
} | |||
} | |||
}, | |||
"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" | |||
} | |||
} | |||
} | |||
} |
@@ -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', | |||
], | |||
]); | |||
} | |||
} |