mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 01:38:41 +00:00
Add json template validation
This commit is contained in:
parent
4ed4caf55b
commit
6cc59da699
35
Module/infoLayout.json
Normal file
35
Module/infoLayout.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": {
|
||||
"id": "^[1-9]\\d*",
|
||||
"internal": "[a-zA-Z0-9]+",
|
||||
"external": "[a-zA-Z0-9]+"
|
||||
},
|
||||
"category": "[a-zA-Z0-9]+",
|
||||
"version": "([0-9]+\\.){2}[0-9]+",
|
||||
"requirements": {
|
||||
".*": ".*"
|
||||
},
|
||||
"creator": {
|
||||
"name": ".+",
|
||||
"website": ".*"
|
||||
},
|
||||
"description": ".+",
|
||||
"directory": "[a-zA-Z0-9]+",
|
||||
"dependencies": {
|
||||
".*": ".*"
|
||||
},
|
||||
"providing": {
|
||||
".*": ".*"
|
||||
},
|
||||
"load": [
|
||||
{
|
||||
"pid": [
|
||||
".*"
|
||||
],
|
||||
"type": "^[1-9]\\d*",
|
||||
"for": "^([1-9]\\d*)|([a-zA-Z0-9]+)",
|
||||
"from": "[a-zA-Z0-9]+",
|
||||
"file": "[a-zA-Z0-9]*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -32,6 +32,6 @@ abstract class DateTime extends ValidatorAbstract
|
|||
*/
|
||||
public static function isValid($value, array $constraints = null) : bool
|
||||
{
|
||||
return (bool) strtotime($value);
|
||||
return (bool) \strtotime($value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
225
Validation/Base/Json.php
Normal file
225
Validation/Base/Json.php
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.2
|
||||
*
|
||||
* @package phpOMS\Validation\Base
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link http://website.orange-management.de
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Validation\Base;
|
||||
|
||||
use phpOMS\Validation\ValidatorAbstract;
|
||||
use phpOMS\Utils\ArrayUtils;
|
||||
|
||||
/**
|
||||
* Validate date.
|
||||
*
|
||||
* @package phpOMS\Validation\Base
|
||||
* @license OMS License 1.0
|
||||
* @link http://website.orange-management.de
|
||||
* @since 1.0.0
|
||||
*/
|
||||
abstract class Json extends ValidatorAbstract
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function isValid($value, array $constraints = null) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate array against a template array.
|
||||
*
|
||||
* @param array $template Template structure
|
||||
* @param array $source Source structure
|
||||
* @param bool $perfect No additional elements in source allowed
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function validateTemplate(array $template, array $source, bool $perfect = false) : bool
|
||||
{
|
||||
$templatePaths = self::createAllViablePaths($template, '');
|
||||
$sourcePaths = self::createAllViablePaths($source, '');
|
||||
|
||||
$isComplete = self::isCompleteSource($templatePaths, $sourcePaths);
|
||||
if (!$isComplete) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($perfect) {
|
||||
$perfectFit = self::hasTemplateDefinition($templatePaths, $sourcePaths);
|
||||
if (!$perfectFit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$isValid = self::isValidSource($templatePaths, $sourcePaths);
|
||||
if (!$isValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all viable paths and their values
|
||||
*
|
||||
* @param array $arr Array
|
||||
* @param string $path Current path
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function createAllViablePaths(array $arr, string $path = '') : array
|
||||
{
|
||||
$paths = [];
|
||||
foreach ($arr as $key => $value) {
|
||||
$tempPath = $path . '/' . $key;
|
||||
|
||||
if (\is_array($value)) {
|
||||
$paths += self::createAllViablePaths($value, $tempPath);
|
||||
} else {
|
||||
$paths[$tempPath] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if source array has additional elements.
|
||||
*
|
||||
* @param array $template Template structure
|
||||
* @param array $source Source structure
|
||||
*
|
||||
* @return bool Returns false in case of undefined elements
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function hasTemplateDefinition(array $template, array $source) : bool
|
||||
{
|
||||
$completePaths = [];
|
||||
foreach ($template as $key => $value) {
|
||||
$key = \str_replace('/0', '/.*', $key);
|
||||
$completePaths[$key] = $value;
|
||||
}
|
||||
|
||||
foreach ($source as $sPath => $sValue) {
|
||||
$hasDefinition = false;
|
||||
|
||||
foreach ($completePaths as $tPath => $tValue) {
|
||||
if ($tPath === $sPath
|
||||
|| \preg_match('~' . \str_replace('/', '\\/', $tPath) . '~', $sPath) === 1
|
||||
) {
|
||||
$hasDefinition = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasDefinition) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if source array is complete
|
||||
*
|
||||
* @param array $template Template structure
|
||||
* @param array $source Source structure
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function isCompleteSource(array $template, array $source) : bool
|
||||
{
|
||||
$completePaths = [];
|
||||
foreach ($template as $key => $value) {
|
||||
$key = \str_replace('/0', '/.*', $key);
|
||||
|
||||
if (\stripos($key, '/.*') !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$completePaths[$key] = $value;
|
||||
}
|
||||
|
||||
foreach ($completePaths as $tPath => $tValue) {
|
||||
$sourceIsComplete = false;
|
||||
|
||||
foreach ($source as $sPath => $sValue) {
|
||||
if ($tPath === $sPath
|
||||
|| \preg_match('~' . \str_replace('/', '\\/', $tPath) . '~', $sPath) === 1
|
||||
) {
|
||||
unset($completePaths[$tPath]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count($completePaths) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if source array is correct
|
||||
*
|
||||
* @param array $template Template structure
|
||||
* @param array $source Source structure
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function isValidSource(array $template, array $source) : bool
|
||||
{
|
||||
$validPaths = [];
|
||||
foreach ($template as $key => $value) {
|
||||
$key = \str_replace('/0', '/\d*', $key);
|
||||
$validPaths[$key] = $value;
|
||||
}
|
||||
|
||||
foreach ($source as $sPath => $sValue) {
|
||||
$sourceIsValid = false;
|
||||
$foundPath = false;
|
||||
|
||||
foreach ($validPaths as $tPath => $tValue) {
|
||||
if (!$foundPath
|
||||
&& ($tPath === $sPath
|
||||
|| \preg_match('~' . \str_replace('/', '\\/', $tPath) . '~', $sPath) === 1)
|
||||
) {
|
||||
$foundPath = true;
|
||||
}
|
||||
|
||||
if (($tPath === $sPath
|
||||
|| \preg_match('~' . \str_replace('/', '\\/', $tPath) . '~', $sPath) === 1)
|
||||
&& ($tValue === $sValue
|
||||
|| \preg_match('~' . ((string) $tValue) . '~', (string) $sValue) === 1)
|
||||
) {
|
||||
$sourceIsValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$sourceIsValid && $foundPath) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
38
tests/Validation/Base/JsonTest.php
Normal file
38
tests/Validation/Base/JsonTest.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.2
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link http://website.orange-management.de
|
||||
*/
|
||||
|
||||
namespace phpOMS\tests\Validation\Base;
|
||||
|
||||
use phpOMS\Validation\Base\Json;
|
||||
|
||||
class JsonTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testJson()
|
||||
{
|
||||
$template = \json_decode(file_get_contents(__DIR__ . '/json/template.json'), true);
|
||||
|
||||
$valid = \json_decode(file_get_contents(__DIR__ . '/json/valid.json'), true);
|
||||
self::assertTrue(Json::validateTemplate($template, $valid));
|
||||
self::assertTrue(Json::validateTemplate($template, $valid, true));
|
||||
|
||||
$additional = \json_decode(file_get_contents(__DIR__ . '/json/additional.json'), true);
|
||||
self::assertTrue(Json::validateTemplate($template, $additional));
|
||||
self::assertFalse(Json::validateTemplate($template, $additional, true));
|
||||
|
||||
$incomplete = \json_decode(file_get_contents(__DIR__ . '/json/incomplete.json'), true);
|
||||
self::assertFalse(Json::validateTemplate($template, $incomplete));
|
||||
|
||||
$invalid = \json_decode(file_get_contents(__DIR__ . '/json/invalid.json'), true);
|
||||
self::assertFalse(Json::validateTemplate($template, $invalid));
|
||||
}
|
||||
}
|
||||
58
tests/Validation/Base/json/additional.json
Normal file
58
tests/Validation/Base/json/additional.json
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"name": {
|
||||
"id": 1001100000,
|
||||
"internal": "Tasks",
|
||||
"external": "Tasks"
|
||||
},
|
||||
"category": "Tools",
|
||||
"version": "1.0.0",
|
||||
"requirements": {
|
||||
"phpOMS": "1.0.0",
|
||||
"phpOMS-db": "1.0.0"
|
||||
},
|
||||
"creator": {
|
||||
"name": "Orange Management",
|
||||
"website": "www.spl1nes.com"
|
||||
},
|
||||
"tooMuch": 1,
|
||||
"description": "Tasks module.",
|
||||
"directory": "Tasks",
|
||||
"dependencies": {
|
||||
"Admin": "1.0.0",
|
||||
"Calendar": "1.0.0",
|
||||
"Media": "1.0.0",
|
||||
"Editor": "1.0.0"
|
||||
},
|
||||
"providing": {
|
||||
"Navigation": "*"
|
||||
},
|
||||
"load": [
|
||||
{
|
||||
"pid": [
|
||||
"/backend/task"
|
||||
],
|
||||
"type": 4,
|
||||
"for": 0,
|
||||
"from": "Tasks",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 4,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 5,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Navigation"
|
||||
}
|
||||
]
|
||||
}
|
||||
56
tests/Validation/Base/json/incomplete.json
Normal file
56
tests/Validation/Base/json/incomplete.json
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"name": {
|
||||
"id": 1001100000,
|
||||
"internal": "Tasks",
|
||||
"external": "Tasks"
|
||||
},
|
||||
"category": "Tools",
|
||||
"requirements": {
|
||||
"phpOMS": "1.0.0",
|
||||
"phpOMS-db": "1.0.0"
|
||||
},
|
||||
"creator": {
|
||||
"name": "Orange Management",
|
||||
"website": "www.spl1nes.com"
|
||||
},
|
||||
"description": "Tasks module.",
|
||||
"directory": "Tasks",
|
||||
"dependencies": {
|
||||
"Admin": "1.0.0",
|
||||
"Calendar": "1.0.0",
|
||||
"Media": "1.0.0",
|
||||
"Editor": "1.0.0"
|
||||
},
|
||||
"providing": {
|
||||
"Navigation": "*"
|
||||
},
|
||||
"load": [
|
||||
{
|
||||
"pid": [
|
||||
"/backend/task"
|
||||
],
|
||||
"type": 4,
|
||||
"for": 0,
|
||||
"from": "Tasks",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 4,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 5,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Navigation"
|
||||
}
|
||||
]
|
||||
}
|
||||
57
tests/Validation/Base/json/invalid.json
Normal file
57
tests/Validation/Base/json/invalid.json
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"name": {
|
||||
"id": "abc",
|
||||
"internal": "Tasks",
|
||||
"external": "Tasks"
|
||||
},
|
||||
"category": "Tools",
|
||||
"version": "1.0.0",
|
||||
"requirements": {
|
||||
"phpOMS": "1.0.0",
|
||||
"phpOMS-db": "1.0.0"
|
||||
},
|
||||
"creator": {
|
||||
"name": "Orange Management",
|
||||
"website": "www.spl1nes.com"
|
||||
},
|
||||
"description": "Tasks module.",
|
||||
"directory": "Tasks",
|
||||
"dependencies": {
|
||||
"Admin": "1.0.0",
|
||||
"Calendar": "1.0.0",
|
||||
"Media": "1.0.0",
|
||||
"Editor": "1.0.0"
|
||||
},
|
||||
"providing": {
|
||||
"Navigation": "*"
|
||||
},
|
||||
"load": [
|
||||
{
|
||||
"pid": [
|
||||
"/backend/task"
|
||||
],
|
||||
"type": 4,
|
||||
"for": 0,
|
||||
"from": "Tasks",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 4,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 5,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Navigation"
|
||||
}
|
||||
]
|
||||
}
|
||||
35
tests/Validation/Base/json/template.json
Normal file
35
tests/Validation/Base/json/template.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": {
|
||||
"id": "^[1-9]\\d*",
|
||||
"internal": "[a-zA-Z0-9]+",
|
||||
"external": "[a-zA-Z0-9]+"
|
||||
},
|
||||
"category": "[a-zA-Z0-9]+",
|
||||
"version": "([0-9]+\\.){2}[0-9]+",
|
||||
"requirements": {
|
||||
".*": ".*"
|
||||
},
|
||||
"creator": {
|
||||
"name": ".+",
|
||||
"website": ".*"
|
||||
},
|
||||
"description": ".+",
|
||||
"directory": "[a-zA-Z0-9]+",
|
||||
"dependencies": {
|
||||
".*": ".*"
|
||||
},
|
||||
"providing": {
|
||||
".*": ".*"
|
||||
},
|
||||
"load": [
|
||||
{
|
||||
"pid": [
|
||||
".*"
|
||||
],
|
||||
"type": "^[1-9]\\d*",
|
||||
"for": "^([1-9]\\d*)|([a-zA-Z0-9]+)",
|
||||
"from": "[a-zA-Z0-9]+",
|
||||
"file": "[a-zA-Z0-9]*"
|
||||
}
|
||||
]
|
||||
}
|
||||
57
tests/Validation/Base/json/valid.json
Normal file
57
tests/Validation/Base/json/valid.json
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"name": {
|
||||
"id": 1001100000,
|
||||
"internal": "Tasks",
|
||||
"external": "Tasks"
|
||||
},
|
||||
"category": "Tools",
|
||||
"version": "1.0.0",
|
||||
"requirements": {
|
||||
"phpOMS": "1.0.0",
|
||||
"phpOMS-db": "1.0.0"
|
||||
},
|
||||
"creator": {
|
||||
"name": "Orange Management",
|
||||
"website": "www.spl1nes.com"
|
||||
},
|
||||
"description": "Tasks module.",
|
||||
"directory": "Tasks",
|
||||
"dependencies": {
|
||||
"Admin": "1.0.0",
|
||||
"Calendar": "1.0.0",
|
||||
"Media": "1.0.0",
|
||||
"Editor": "1.0.0"
|
||||
},
|
||||
"providing": {
|
||||
"Navigation": "*"
|
||||
},
|
||||
"load": [
|
||||
{
|
||||
"pid": [
|
||||
"/backend/task"
|
||||
],
|
||||
"type": 4,
|
||||
"for": 0,
|
||||
"from": "Tasks",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 4,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Tasks"
|
||||
},
|
||||
{
|
||||
"pid": [
|
||||
"/backend"
|
||||
],
|
||||
"type": 5,
|
||||
"from": "Tasks",
|
||||
"for": "Navigation",
|
||||
"file": "Navigation"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user