ldc-crm-client/src/Utils.php

340 lines
13 KiB
PHP
Raw Normal View History

<?php
namespace LDC\LDCCRM;
use Dotenv\Dotenv;
use LDC\LDCCRM\Enums\HttpMethods;
use LDC\LDCCRM\Exceptions\ValidationException;
use LDC\LDCCRM\Transport\Request;
use Respect\Validation\Validator;
/**
* This is the LDCCRM utility class
*
* @category Utility
* @uses \LDC\LDCCRM\Enums\HttpMethods
* @uses \LDC\LDCCRM\Transport\Request
*
* @package LDCCrmClient
* @subpackage utilities
*/
class Utils
{
/**
* Package infos
*
* @var array
*/
private static $packageInfos;
/**
* The env config
*
* @var array
*/
private static $config;
/**
* Loaded translations
*
* @var array
*/
private static $translations = [];
/**
* Create a new Validator instance.
*
* @param array $data
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return \Illuminate\Validation\Validator
*/
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
public static function makeValidator(
array $data,
array $rules
): object {
foreach ($rules as $attribute => $attrRules) {
$validators = [];
if (\is_string($attrRules)) {
$attrRules = \explode('|', $attrRules);
}
foreach ($attrRules as $rule) {
$closureFail = function ($message) {
throw new ValidationException($message);
};
$closure = null;
$rParams = [];
if (\is_callable($rule) and !is_string($rule)) {
$closure = $rule;
$rule = 'closure';
} elseif (\strpos($rule, ':') !== false) {
$rParams = \explode(':', $rule, 2);
$rule = \array_shift($rParams);
}
switch ($rule) {
case 'required':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return isset($data[$attribute]);
},
'error' => self::translate($attribute) . ' est obligatoire'
];
break;
case 'sometimes':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return true;
},
'error' => self::translate($attribute) . ' est falcutatif'
];
break;
case 'int':
$validators[] =
[
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return \is_int($data[$attribute]);
},
'error' => self::translate($attribute) . ' doit être un entier'
];
break;
case 'string':
$validators[] =
[
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return \is_string($data[$attribute]);
},
'error' => self::translate($attribute) . ' doit être une chaine de charactères'
];
break;
case 'bool':
$validators[] =
[
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return \is_bool($data[$attribute]);
},
'error' => self::translate($attribute) . ' doit être un booléen'
];
break;
case 'min':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute, $rParams) {
return \is_string($data[$attribute]) and
\strlen($data[$attribute]) >= (int)$rParams[0];
},
'error' => self::translate($attribute) . " doit avoir moins ou $rParams[0] caratères"
];
break;
case 'max':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute, $rParams) {
return \is_string($data[$attribute]) and
\strlen($data[$attribute]) <= (int)$rParams[0];
},
'error' => self::translate($attribute) . " doit avoir plus ou $rParams[0] caratères"
];
break;
case 'uuid':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return Validator::uuid()->validate($data[$attribute]);
},
'error' => self::translate($attribute) . ' doit être un uuid'
];
break;
case 'mixedCase':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return \preg_match('/[a-z]/', $data[$attribute]) and
\preg_match('/[A-Z]/', $data[$attribute]);
},
'error' => self::translate($attribute) . ' doit contenir des lettre minuscules et majuscules'
];
break;
case 'containDigit':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return \preg_match('/[0-9]/', $data[$attribute]);
},
'error' => self::translate($attribute) . ' doit contenir au moins un chiffre'
];
break;
case 'containSymbol':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return \preg_match('/[^a-zA-Z0-9]/', $data[$attribute]);
},
// phpcs:ignore Generic.Files.LineLength.TooLong
'error' => self::translate($attribute) . ' doit contenir au moins un caractère spécial comme une virgule par exemple'
];
break;
case 'date':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return Validator::dateTime()->validate($data[$attribute]);
},
'error' => self::translate($attribute) . ' doit être une date valide'
];
break;
case 'date_format':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute, $rParams) {
return Validator::dateTime($rParams[0])->validate($data[$attribute]);
},
'error' => self::translate($attribute) . " doit être une date au format $rParams[0]"
];
break;
case 'email':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute) {
return Validator::email()->validate($data[$attribute]);
},
'error' => self::translate($attribute) . ' doit être un email valide'
];
break;
case 'closure':
$validators[] = [
'type' => $rule,
'validate' => function () use ($data, $attribute, $closure, $closureFail) {
$closure($attribute, $data[$attribute], $closureFail);
return true;
},
'error' => self::translate($attribute) . ' doit être validé'
];
break;
default:
throw new \Exception("Unknown validation rule $rule " . implode(': ', $rParams));
}
}
}
return function () use ($validators) {
foreach ($validators as $validator) {
if (!$validator['validate']()) {
throw new ValidationException($validator['error']);
}
}
};
}
/**
* Get config
*
* @param string $key
* @param string $default
* @return string|null
* @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException
*/
public static function getConfig(string $key, string $default = null): ?string
{
$value = null;
if (function_exists('config')) {
$value = \config($key, $default);
}
try {
if (!self::$config) {
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
self::$config = $dotenv->load();
}
} catch (\Dotenv\Exception\InvalidPathException $e) {
return $value;
}
if (isset(self::$config[$key])) {
$value = self::$config[$key];
}
return $value;
}
/**
* Generate a Request from the route name
*
* @param string $routeName
* @param array $query params to pass on to the route
* @param array $data http body params
* @return Request
*/
public static function getResquest(string $routeName, array $query = [], array $data = []): Request
{
// convert bool to integer
$query = \array_map(function ($v) {
return is_bool($v) ? (int)$v : $v;
}, $query);
$data = \array_map(function ($v) {
return is_bool($v) ? (int)$v : $v;
}, $data);
$routes = \json_decode(\file_get_contents(__DIR__ . '/routes.json'), true);
if (!isset($routes[$routeName])) {
throw new \Exception("Unknown route $routeName from the crm");
}
$route = $routes[$routeName];
$matches = [];
$matchedIndex = [];
\preg_match_all('/{([\w-]*)}/', $route['uri'], $matches);
if (\count($matches[0])) {
foreach ($matches[0] as $k => $match) {
if (!isset($query[$matches[1][$k]])) {
throw new \Exception(sprintf('Missing required parameter %s', $matches[1][$k]));
}
$route['uri'] = str_replace($match, $query[$matches[1][$k]], $route['uri']);
$matchedIndex[$matches[1][$k]] = $query[$matches[1][$k]];
}
}
$query = \array_flip($query);
foreach ($matchedIndex as $key) {
unset($query[$key]);
}
$query = \array_flip($query);
if (count($query)) {
$route['uri'] = sprintf('%s?%s', $route['uri'], \http_build_query($query));
}
return new Request(HttpMethods::make($route['methods'][0]), $route['uri'], [], $data);
}
/**
* Get composer.json infos
*
* @return array
*/
public static function getPackageInfo(): array
{
if (!static::$packageInfos) {
static::$packageInfos = \json_decode(\file_get_contents(__DIR__ . '/../composer.json'), true);
}
return static::$packageInfos;
}
public static function translate(string $key, string $lang = 'fr'): string
{
try {
if (!array_key_exists($lang, self::$translations)) {
self::$translations = require __DIR__ . "/../resources/lang/$lang.php";
}
} finally {
if (!isset(self::$translations['validation'][$key])) {
return $key;
} else {
return self::$translations['validation'][$key];
}
}
}
}