feat: add validation and use opencart logger
This commit is contained in:
@@ -8,6 +8,7 @@ use Cart\Currency;
|
|||||||
use Cart\Tax;
|
use Cart\Tax;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageTool;
|
use Openguru\OpenCartFramework\ImageTool\ImageTool;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||||
|
use Openguru\OpenCartFramework\Logger\OpenCartLogAdapter;
|
||||||
|
|
||||||
$sysLibPath = rtrim(DIR_SYSTEM, '/') . '/library/oc_telegram_shop';
|
$sysLibPath = rtrim(DIR_SYSTEM, '/') . '/library/oc_telegram_shop';
|
||||||
$basePath = rtrim(DIR_APPLICATION, '/') . '/..';
|
$basePath = rtrim(DIR_APPLICATION, '/') . '/..';
|
||||||
@@ -26,6 +27,9 @@ class Controllerextensiontgshophandle extends Controller
|
|||||||
{
|
{
|
||||||
public function index(): void
|
public function index(): void
|
||||||
{
|
{
|
||||||
|
$this->load->model('checkout/order');
|
||||||
|
$this->session->data['language'] = $this->config->get('config_language');
|
||||||
|
|
||||||
$app = ApplicationFactory::create([
|
$app = ApplicationFactory::create([
|
||||||
'app_enabled' => filter_var($this->config->get('module_tgshop_status'), FILTER_VALIDATE_BOOLEAN),
|
'app_enabled' => filter_var($this->config->get('module_tgshop_status'), FILTER_VALIDATE_BOOLEAN),
|
||||||
'oc_config_tax' => $this->config->get('config_tax'),
|
'oc_config_tax' => $this->config->get('config_tax'),
|
||||||
@@ -69,40 +73,22 @@ class Controllerextensiontgshophandle extends Controller
|
|||||||
'cache_products_main' => 60 * 10,
|
'cache_products_main' => 60 * 10,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$app->bind(Url::class, function () {
|
|
||||||
return $this->url;
|
|
||||||
});
|
|
||||||
|
|
||||||
$app->bind(Currency::class, function () {
|
|
||||||
return $this->currency;
|
|
||||||
});
|
|
||||||
|
|
||||||
$app->bind(Tax::class, function () {
|
|
||||||
return $this->tax;
|
|
||||||
});
|
|
||||||
|
|
||||||
$app->bind(OcModelCatalogProductAdapter::class, function () {
|
$app->bind(OcModelCatalogProductAdapter::class, function () {
|
||||||
$this->load->model('catalog/product');
|
$this->load->model('catalog/product');
|
||||||
return new OcModelCatalogProductAdapter($this->model_catalog_product);
|
return new OcModelCatalogProductAdapter($this->model_catalog_product);
|
||||||
});
|
});
|
||||||
|
|
||||||
$app->bind(ImageToolInterface::class, function () {
|
$app->bind(Url::class, fn () => $this->url);
|
||||||
return new ImageTool(DIR_IMAGE, HTTPS_SERVER);
|
$app->bind(Currency::class, fn () => $this->currency);
|
||||||
});
|
$app->bind(Tax::class, fn () => $this->tax);
|
||||||
|
$app->bind(ImageToolInterface::class, fn () => new ImageTool(DIR_IMAGE, HTTPS_SERVER));
|
||||||
|
$app->bind(Cart::class, fn () => $this->cart);
|
||||||
|
$app->bind(OcRegistryDecorator::class, fn () => new OcRegistryDecorator($this->registry));
|
||||||
|
$app->singleton(Log::class, fn () => $this->log);
|
||||||
|
|
||||||
$app->bind(Cart::class, function () {
|
$app
|
||||||
return $this->cart;
|
->withLogger(fn () => new OpenCartLogAdapter($this->log, 'TeleCart'))
|
||||||
});
|
->bootAndHandleRequest();
|
||||||
|
|
||||||
$app->bind(OcRegistryDecorator::class, function () {
|
|
||||||
return new OcRegistryDecorator($this->registry);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->load->model('checkout/order');
|
|
||||||
|
|
||||||
$this->session->data['language'] = $this->config->get('config_language');
|
|
||||||
|
|
||||||
$app->bootAndHandleRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractPureJs($input)
|
function extractPureJs($input)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Openguru\\OpenCartFramework\\": "framework/",
|
"Openguru\\OpenCartFramework\\": "framework/",
|
||||||
"App\\": "src/"
|
"App\\": "src/",
|
||||||
|
"Tests\\": "tests/"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"framework/Support/helpers.php"
|
"framework/Support/helpers.php"
|
||||||
@@ -21,13 +22,13 @@
|
|||||||
"psr/container": "^2.0",
|
"psr/container": "^2.0",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"intervention/image": "^2.7",
|
"intervention/image": "^2.7",
|
||||||
"rakit/validation": "^1.4",
|
|
||||||
"vlucas/phpdotenv": "^5.6",
|
"vlucas/phpdotenv": "^5.6",
|
||||||
"guzzlehttp/guzzle": "^7.9",
|
"guzzlehttp/guzzle": "^7.9",
|
||||||
"symfony/cache": "^5.4"
|
"symfony/cache": "^5.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"roave/security-advisories": "dev-latest",
|
"roave/security-advisories": "dev-latest",
|
||||||
"phpstan/phpstan": "^2.1"
|
"phpstan/phpstan": "^2.1",
|
||||||
|
"phpunit/phpunit": "^9.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Openguru\OpenCartFramework;
|
namespace Openguru\OpenCartFramework;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
use Dotenv\Dotenv;
|
use Dotenv\Dotenv;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Openguru\OpenCartFramework\Config\Settings;
|
use Openguru\OpenCartFramework\Config\Settings;
|
||||||
@@ -9,6 +10,7 @@ use Openguru\OpenCartFramework\Container\Container;
|
|||||||
use Openguru\OpenCartFramework\Http\JsonResponse;
|
use Openguru\OpenCartFramework\Http\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Logger\Logger;
|
use Openguru\OpenCartFramework\Logger\Logger;
|
||||||
|
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
||||||
use Openguru\OpenCartFramework\Router\Router;
|
use Openguru\OpenCartFramework\Router\Router;
|
||||||
use Openguru\OpenCartFramework\Support\ExecutionTimeProfiler;
|
use Openguru\OpenCartFramework\Support\ExecutionTimeProfiler;
|
||||||
|
|
||||||
@@ -18,6 +20,16 @@ class Application extends Container
|
|||||||
private static array $events = [];
|
private static array $events = [];
|
||||||
private array $serviceProviders = [];
|
private array $serviceProviders = [];
|
||||||
private array $middlewareStack = [];
|
private array $middlewareStack = [];
|
||||||
|
private LoggerInterface $logger;
|
||||||
|
|
||||||
|
public function __construct(array $config)
|
||||||
|
{
|
||||||
|
parent::__construct($config);
|
||||||
|
|
||||||
|
// Fallback logger
|
||||||
|
$path = rtrim($this->getConfigValue('logs.path'), '/') . '/oc_telegram_shop.log';
|
||||||
|
$this->logger = new Logger($path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ExecutionTimeProfiler
|
* @var ExecutionTimeProfiler
|
||||||
@@ -42,10 +54,7 @@ class Application extends Container
|
|||||||
return $container;
|
return $container;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->singleton(Logger::class, function (Container $container) {
|
$this->singleton(LoggerInterface::class, fn () => $this->logger);
|
||||||
$path = $container->getConfigValue('logs.path') . '/oc_telegram_shop.log';
|
|
||||||
return new Logger($path, Logger::LEVEL_INFO);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->singleton(Settings::class, function (Container $container) {
|
$this->singleton(Settings::class, function (Container $container) {
|
||||||
return new Settings($container->getConfigValue());
|
return new Settings($container->getConfigValue());
|
||||||
@@ -55,7 +64,7 @@ class Application extends Container
|
|||||||
$dotenv->load();
|
$dotenv->load();
|
||||||
|
|
||||||
$errorHandler = new ErrorHandler(
|
$errorHandler = new ErrorHandler(
|
||||||
$this->get(Logger::class),
|
$this->get(LoggerInterface::class),
|
||||||
$this,
|
$this,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -89,17 +98,17 @@ class Application extends Container
|
|||||||
|
|
||||||
[$controller, $method] = $action;
|
[$controller, $method] = $action;
|
||||||
|
|
||||||
if (!class_exists($controller) || !method_exists($controller, $method)) {
|
if (! class_exists($controller) || ! method_exists($controller, $method)) {
|
||||||
throw new InvalidArgumentException('Invalid action: ' . $controller . '->' . $method);
|
throw new InvalidArgumentException('Invalid action: ' . $controller . '->' . $method);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->profiler->addCheckpoint('Handle Middlewares.');
|
$this->profiler->addCheckpoint('Handle Middlewares.');
|
||||||
|
|
||||||
$next = fn($req) => $this->call($controller, $method);
|
$next = fn ($req) => $this->call($controller, $method);
|
||||||
|
|
||||||
foreach (array_reverse($this->middlewareStack) as $class) {
|
foreach (array_reverse($this->middlewareStack) as $class) {
|
||||||
$instance = $this->get($class);
|
$instance = $this->get($class);
|
||||||
$next = static fn($req) => $instance->handle($req, $next);
|
$next = static fn ($req) => $instance->handle($req, $next);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $next($request);
|
$response = $next($request);
|
||||||
@@ -130,4 +139,11 @@ class Application extends Container
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withLogger(Closure $closure): Application
|
||||||
|
{
|
||||||
|
$this->logger = $closure();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
|||||||
use Openguru\OpenCartFramework\Exceptions\NonLoggableExceptionInterface;
|
use Openguru\OpenCartFramework\Exceptions\NonLoggableExceptionInterface;
|
||||||
use Openguru\OpenCartFramework\Http\JsonResponse;
|
use Openguru\OpenCartFramework\Http\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Openguru\OpenCartFramework\Http\Response;
|
||||||
use Openguru\OpenCartFramework\Logger\Logger;
|
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,10 +15,10 @@ use Throwable;
|
|||||||
*/
|
*/
|
||||||
class ErrorHandler
|
class ErrorHandler
|
||||||
{
|
{
|
||||||
private $logger;
|
private LoggerInterface $logger;
|
||||||
private Application $app;
|
private Application $app;
|
||||||
|
|
||||||
public function __construct(Logger $logger, Application $application)
|
public function __construct(LoggerInterface $logger, Application $application)
|
||||||
{
|
{
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->app = $application;
|
$this->app = $application;
|
||||||
|
|||||||
@@ -4,24 +4,20 @@ namespace Openguru\OpenCartFramework\Logger;
|
|||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class Logger
|
class Logger implements LoggerInterface
|
||||||
{
|
{
|
||||||
private $logFile;
|
private $logFile;
|
||||||
private $logLevel;
|
private $logLevel;
|
||||||
private $maxFileSize; // Максимальный размер файла в байтах
|
private $maxFileSize; // Максимальный размер файла в байтах
|
||||||
|
|
||||||
public const LEVEL_INFO = 1;
|
public function __construct($logFile, $logLevel = LoggerInterface::LEVEL_INFO, $maxFileSize = 1048576)
|
||||||
public const LEVEL_WARNING = 2;
|
|
||||||
public const LEVEL_ERROR = 3;
|
|
||||||
|
|
||||||
public function __construct($logFile, $logLevel = self::LEVEL_INFO, $maxFileSize = 1048576)
|
|
||||||
{
|
{
|
||||||
$this->logFile = $logFile;
|
$this->logFile = $logFile;
|
||||||
$this->logLevel = $logLevel;
|
$this->logLevel = $logLevel;
|
||||||
$this->maxFileSize = $maxFileSize;
|
$this->maxFileSize = $maxFileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function log($message, $level = self::LEVEL_INFO)
|
public function log($message, $level = LoggerInterface::LEVEL_INFO)
|
||||||
{
|
{
|
||||||
if ($level < $this->logLevel) {
|
if ($level < $this->logLevel) {
|
||||||
return; // Не логируем, если уровень ниже установленного
|
return; // Не логируем, если уровень ниже установленного
|
||||||
@@ -39,11 +35,11 @@ class Logger
|
|||||||
private function getLevelString($level): string
|
private function getLevelString($level): string
|
||||||
{
|
{
|
||||||
switch ($level) {
|
switch ($level) {
|
||||||
case self::LEVEL_INFO:
|
case LoggerInterface::LEVEL_INFO:
|
||||||
return 'INFO';
|
return 'INFO';
|
||||||
case self::LEVEL_WARNING:
|
case LoggerInterface::LEVEL_WARNING:
|
||||||
return 'WARNING';
|
return 'WARNING';
|
||||||
case self::LEVEL_ERROR:
|
case LoggerInterface::LEVEL_ERROR:
|
||||||
return 'ERROR';
|
return 'ERROR';
|
||||||
default:
|
default:
|
||||||
return 'UNKNOWN';
|
return 'UNKNOWN';
|
||||||
@@ -52,17 +48,17 @@ class Logger
|
|||||||
|
|
||||||
public function info(string $message): void
|
public function info(string $message): void
|
||||||
{
|
{
|
||||||
$this->log($message, self::LEVEL_INFO);
|
$this->log($message, LoggerInterface::LEVEL_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function warning(string $message): void
|
public function warning(string $message): void
|
||||||
{
|
{
|
||||||
$this->log($message, self::LEVEL_WARNING);
|
$this->log($message, LoggerInterface::LEVEL_WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function error(string $message): void
|
public function error(string $message): void
|
||||||
{
|
{
|
||||||
$this->log($message, self::LEVEL_ERROR);
|
$this->log($message, LoggerInterface::LEVEL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function rotateLogs(): void
|
private function rotateLogs(): void
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Logger;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
interface LoggerInterface
|
||||||
|
{
|
||||||
|
public const LEVEL_INFO = 1;
|
||||||
|
public const LEVEL_WARNING = 2;
|
||||||
|
public const LEVEL_ERROR = 3;
|
||||||
|
|
||||||
|
public function log($message, $level = self::LEVEL_INFO);
|
||||||
|
|
||||||
|
public function info(string $message): void;
|
||||||
|
|
||||||
|
public function warning(string $message): void;
|
||||||
|
|
||||||
|
public function error(string $message): void;
|
||||||
|
|
||||||
|
public function logException(Throwable $exception): void;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Logger;
|
||||||
|
|
||||||
|
use Log;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class OpenCartLogAdapter implements LoggerInterface
|
||||||
|
{
|
||||||
|
private Log $ocLogger;
|
||||||
|
private string $namespace;
|
||||||
|
|
||||||
|
public function __construct(Log $ocLogger, string $namespace)
|
||||||
|
{
|
||||||
|
$this->ocLogger = $ocLogger;
|
||||||
|
$this->namespace = $namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function log($message, $level = self::LEVEL_INFO): void
|
||||||
|
{
|
||||||
|
$this->ocLogger->write(
|
||||||
|
sprintf(
|
||||||
|
"[%s] [%s] %s\n",
|
||||||
|
$this->namespace,
|
||||||
|
$this->getLevelString($level),
|
||||||
|
$message
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function info(string $message): void
|
||||||
|
{
|
||||||
|
$this->log($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function warning(string $message): void
|
||||||
|
{
|
||||||
|
$this->log($message, self::LEVEL_WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function error(string $message): void
|
||||||
|
{
|
||||||
|
$this->log($message, self::LEVEL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logException(Throwable $exception): void
|
||||||
|
{
|
||||||
|
$this->error(
|
||||||
|
sprintf(
|
||||||
|
"Fatal error %s in %s on line %d\n%s",
|
||||||
|
$exception->getMessage(),
|
||||||
|
$exception->getFile(),
|
||||||
|
$exception->getLine(),
|
||||||
|
$exception->getTraceAsString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLevelString($level): string
|
||||||
|
{
|
||||||
|
switch ($level) {
|
||||||
|
case LoggerInterface::LEVEL_INFO:
|
||||||
|
return 'INFO';
|
||||||
|
case LoggerInterface::LEVEL_WARNING:
|
||||||
|
return 'WARNING';
|
||||||
|
case LoggerInterface::LEVEL_ERROR:
|
||||||
|
return 'ERROR';
|
||||||
|
default:
|
||||||
|
return 'UNKNOWN';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,17 +3,14 @@
|
|||||||
namespace Openguru\OpenCartFramework\Telegram;
|
namespace Openguru\OpenCartFramework\Telegram;
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Openguru\OpenCartFramework\Logger\Logger;
|
|
||||||
|
|
||||||
class TelegramService
|
class TelegramService
|
||||||
{
|
{
|
||||||
private Logger $logger;
|
|
||||||
private Client $client;
|
private Client $client;
|
||||||
private ?string $botToken;
|
private ?string $botToken;
|
||||||
|
|
||||||
public function __construct(Logger $logger, ?string $botToken = null)
|
public function __construct(?string $botToken = null)
|
||||||
{
|
{
|
||||||
$this->logger = $logger;
|
|
||||||
$this->botToken = $botToken;
|
$this->botToken = $botToken;
|
||||||
$this->client = $this->createGuzzleClient("https://api.telegram.org/bot{$botToken}/");
|
$this->client = $this->createGuzzleClient("https://api.telegram.org/bot{$botToken}/");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace Openguru\OpenCartFramework\Telegram;
|
|||||||
|
|
||||||
use Openguru\OpenCartFramework\Application;
|
use Openguru\OpenCartFramework\Application;
|
||||||
use Openguru\OpenCartFramework\Container\ServiceProvider;
|
use Openguru\OpenCartFramework\Container\ServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Logger\Logger;
|
|
||||||
|
|
||||||
class TelegramServiceProvider extends ServiceProvider
|
class TelegramServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@@ -12,10 +11,7 @@ class TelegramServiceProvider extends ServiceProvider
|
|||||||
{
|
{
|
||||||
$this->container->singleton(TelegramService::class, function (Application $app) {
|
$this->container->singleton(TelegramService::class, function (Application $app) {
|
||||||
$botToken = $app->getConfigValue('telegram.bot_token');
|
$botToken = $app->getConfigValue('telegram.bot_token');
|
||||||
return new TelegramService(
|
return new TelegramService($botToken);
|
||||||
$app->get(Logger::class),
|
|
||||||
$botToken,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->container->singleton(SignatureValidator::class, function (Application $app) {
|
$this->container->singleton(SignatureValidator::class, function (Application $app) {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator;
|
||||||
|
|
||||||
|
class ErrorBag
|
||||||
|
{
|
||||||
|
private array $errors;
|
||||||
|
|
||||||
|
public function __construct(array $errors = [])
|
||||||
|
{
|
||||||
|
$this->errors = $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count(): int
|
||||||
|
{
|
||||||
|
return count($this->errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function put(string $field, string $message): void
|
||||||
|
{
|
||||||
|
$this->errors[$field][] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function first(): array
|
||||||
|
{
|
||||||
|
foreach ($this->errors as $error) {
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function firstOfAll(): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($this->errors as $field => $errors) {
|
||||||
|
if (count($errors) > 0) {
|
||||||
|
$result[$field] = $errors[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ValidationRuleNotFoundException extends Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator\ValidationRules;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
|
||||||
|
class Email implements ValidationRuleInterface
|
||||||
|
{
|
||||||
|
public function validate(string $field, array $input, Closure $fail): void
|
||||||
|
{
|
||||||
|
$email = $input[$field] ?? '';
|
||||||
|
|
||||||
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$fail('Email is not valid');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator\ValidationRules;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
|
||||||
|
class Required implements ValidationRuleInterface
|
||||||
|
{
|
||||||
|
public function validateRequired($value): bool
|
||||||
|
{
|
||||||
|
if (is_null($value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) && trim($value) === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_countable($value) && count($value) < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate(string $field, array $input, Closure $fail): void
|
||||||
|
{
|
||||||
|
$value = $input[$field] ?? null;
|
||||||
|
|
||||||
|
if ($this->validateRequired($value) === false) {
|
||||||
|
$fail(':field is required');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator\ValidationRules;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
|
||||||
|
interface ValidationRuleInterface
|
||||||
|
{
|
||||||
|
public function validate(string $field, array $input, Closure $fail): void;
|
||||||
|
}
|
||||||
@@ -2,23 +2,89 @@
|
|||||||
|
|
||||||
namespace Openguru\OpenCartFramework\Validator;
|
namespace Openguru\OpenCartFramework\Validator;
|
||||||
|
|
||||||
class Validator
|
use Openguru\OpenCartFramework\Validator\ValidationRules\ValidationRuleInterface;
|
||||||
{
|
|
||||||
private $input;
|
|
||||||
private $rules;
|
|
||||||
|
|
||||||
public function __construct(array $input, array $rules)
|
class Validator implements ValidatorInterface
|
||||||
|
{
|
||||||
|
private array $input;
|
||||||
|
private array $rules;
|
||||||
|
private ErrorBag $errors;
|
||||||
|
private array $customMessages;
|
||||||
|
private array $fieldNames;
|
||||||
|
|
||||||
|
public function __construct(array $validationRules = [], array $customMessages = [])
|
||||||
|
{
|
||||||
|
$this->validationRules = $validationRules;
|
||||||
|
$this->customMessages = $customMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function make(array $input, array $rules, array $fieldNames = []): Validator
|
||||||
{
|
{
|
||||||
$this->input = $input;
|
$this->input = $input;
|
||||||
$this->rules = $rules;
|
$this->rules = $rules;
|
||||||
|
$this->errors = new ErrorBag();
|
||||||
|
$this->fieldNames = $fieldNames;
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate(): bool
|
/**
|
||||||
|
* @throws ValidationRuleNotFoundException
|
||||||
|
*/
|
||||||
|
private function validate(): void
|
||||||
{
|
{
|
||||||
foreach ($this->rules as $name => $rule) {
|
foreach ($this->rules as $field => $rule) {
|
||||||
$components = explode('|', $rule);
|
$parts = $this->extractParts($rule);
|
||||||
|
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
$validationRule = $this->resolveRuleClass($part);
|
||||||
|
|
||||||
|
$validationRule->validate($field, $this->input, function ($message) use ($part, $field) {
|
||||||
|
$this->errors->put($field, $this->formatMessage($message, $part, $field));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ValidationRuleNotFoundException
|
||||||
|
*/
|
||||||
|
public function fails(): bool
|
||||||
|
{
|
||||||
|
$this->validate();
|
||||||
|
|
||||||
|
return $this->errors->count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function extractParts($rule): array
|
||||||
|
{
|
||||||
|
return explode('|', $rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ValidationRuleNotFoundException
|
||||||
|
*/
|
||||||
|
private function resolveRuleClass($part): ValidationRuleInterface
|
||||||
|
{
|
||||||
|
$lazyClass = $this->validationRules[$part] ?? null;
|
||||||
|
|
||||||
|
if ($lazyClass === null) {
|
||||||
|
throw new ValidationRuleNotFoundException('Unknown rule "' . $part);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return $lazyClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrors(): ErrorBag
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatMessage(string $message, string $rule, string $field): string
|
||||||
|
{
|
||||||
|
$message = $this->customMessages[$rule] ?? $message;
|
||||||
|
$field = $this->fieldNames[$field] ?? $field;
|
||||||
|
|
||||||
|
return str_replace(':field', $field, $message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator;
|
||||||
|
|
||||||
|
interface ValidatorInterface
|
||||||
|
{
|
||||||
|
public function make(array $input, array $rules, array $fieldNames = []): ValidatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ValidationRuleNotFoundException
|
||||||
|
*/
|
||||||
|
public function fails(): bool;
|
||||||
|
|
||||||
|
public function getErrors(): ErrorBag;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Validator;
|
||||||
|
|
||||||
|
use Openguru\OpenCartFramework\Container\ServiceProvider;
|
||||||
|
use Openguru\OpenCartFramework\Validator\ValidationRules\Email;
|
||||||
|
use Openguru\OpenCartFramework\Validator\ValidationRules\Required;
|
||||||
|
|
||||||
|
class ValidatorServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'required' => fn () => $this->container->get(Required::class),
|
||||||
|
'email' => fn () => $this->container->get(Email::class),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
$this->container->bind(ValidatorInterface::class, function () {
|
||||||
|
$langCode = $this->container->getConfigValue('', 'ru');
|
||||||
|
$translationsFile = __DIR__ . "/translations/$langCode.php";
|
||||||
|
|
||||||
|
if (! file_exists($translationsFile)) {
|
||||||
|
$translationsFile = __DIR__ . "/lang/en.php";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Validator($this->rules(), require $translationsFile);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'required' => ':field обязательно для заполнения.',
|
||||||
|
'email' => 'Неверный e-mail.',
|
||||||
|
];
|
||||||
@@ -10,6 +10,7 @@ use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
|||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Openguru\OpenCartFramework\Telegram\TelegramServiceProvider;
|
use Openguru\OpenCartFramework\Telegram\TelegramServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Telegram\TelegramValidateInitDataMiddleware;
|
use Openguru\OpenCartFramework\Telegram\TelegramValidateInitDataMiddleware;
|
||||||
|
use Openguru\OpenCartFramework\Validator\ValidatorServiceProvider;
|
||||||
|
|
||||||
class ApplicationFactory
|
class ApplicationFactory
|
||||||
{
|
{
|
||||||
@@ -24,6 +25,7 @@ class ApplicationFactory
|
|||||||
RouteServiceProvider::class,
|
RouteServiceProvider::class,
|
||||||
AppServiceProvider::class,
|
AppServiceProvider::class,
|
||||||
TelegramServiceProvider::class,
|
TelegramServiceProvider::class,
|
||||||
|
ValidatorServiceProvider::class,
|
||||||
])
|
])
|
||||||
->withMiddlewares([
|
->withMiddlewares([
|
||||||
TelegramValidateInitDataMiddleware::class,
|
TelegramValidateInitDataMiddleware::class,
|
||||||
|
|||||||
@@ -3,12 +3,18 @@
|
|||||||
namespace App\Decorators;
|
namespace App\Decorators;
|
||||||
|
|
||||||
use Cart\Cart;
|
use Cart\Cart;
|
||||||
|
use Cart\Currency;
|
||||||
|
use Config;
|
||||||
use Loader;
|
use Loader;
|
||||||
use Registry;
|
use Registry;
|
||||||
|
use Session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property Loader $load
|
* @property Loader $load
|
||||||
* @property Cart $cart
|
* @property Cart $cart
|
||||||
|
* @property Session $session
|
||||||
|
* @property Currency $currency
|
||||||
|
* @property Config $config
|
||||||
* @property \ModelCatalogProduct $model_catalog_product
|
* @property \ModelCatalogProduct $model_catalog_product
|
||||||
*/
|
*/
|
||||||
class OcRegistryDecorator
|
class OcRegistryDecorator
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Exceptions;
|
namespace App\Exceptions;
|
||||||
|
|
||||||
use Rakit\Validation\ErrorBag;
|
use Openguru\OpenCartFramework\Validator\ErrorBag;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ use Exception;
|
|||||||
use Openguru\OpenCartFramework\Config\Settings;
|
use Openguru\OpenCartFramework\Config\Settings;
|
||||||
use Openguru\OpenCartFramework\Http\JsonResponse;
|
use Openguru\OpenCartFramework\Http\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Logger\Logger;
|
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
class ProductsHandler
|
class ProductsHandler
|
||||||
{
|
{
|
||||||
private Settings $settings;
|
private Settings $settings;
|
||||||
private ProductsService $productsService;
|
private ProductsService $productsService;
|
||||||
private Logger $logger;
|
private LoggerInterface $logger;
|
||||||
|
|
||||||
public function __construct(Settings $settings, ProductsService $productsService, Logger $logger)
|
public function __construct(Settings $settings, ProductsService $productsService, LoggerInterface $logger)
|
||||||
{
|
{
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->productsService = $productsService;
|
$this->productsService = $productsService;
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Decorators\OcRegistryDecorator;
|
use App\Decorators\OcRegistryDecorator;
|
||||||
use App\Exceptions\OrderValidationFailedException;
|
use App\Exceptions\OrderValidationFailedException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Openguru\OpenCartFramework\Config\Settings;
|
use Openguru\OpenCartFramework\Config\Settings;
|
||||||
use Openguru\OpenCartFramework\Logger\Logger;
|
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
|
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||||
use Rakit\Validation\Validator;
|
use Openguru\OpenCartFramework\Validator\ValidationRuleNotFoundException;
|
||||||
|
use Openguru\OpenCartFramework\Validator\ValidatorInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
class OrderCreateService
|
class OrderCreateService
|
||||||
@@ -20,7 +23,8 @@ class OrderCreateService
|
|||||||
private OcRegistryDecorator $oc;
|
private OcRegistryDecorator $oc;
|
||||||
private Settings $settings;
|
private Settings $settings;
|
||||||
private TelegramService $telegramService;
|
private TelegramService $telegramService;
|
||||||
private Logger $logger;
|
private LoggerInterface $logger;
|
||||||
|
private ValidatorInterface $validator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ConnectionInterface $database,
|
ConnectionInterface $database,
|
||||||
@@ -28,7 +32,8 @@ class OrderCreateService
|
|||||||
OcRegistryDecorator $registry,
|
OcRegistryDecorator $registry,
|
||||||
Settings $settings,
|
Settings $settings,
|
||||||
TelegramService $telegramService,
|
TelegramService $telegramService,
|
||||||
Logger $logger
|
LoggerInterface $logger,
|
||||||
|
ValidatorInterface $validator
|
||||||
) {
|
) {
|
||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
$this->cartService = $cartService;
|
$this->cartService = $cartService;
|
||||||
@@ -36,11 +41,16 @@ class OrderCreateService
|
|||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->telegramService = $telegramService;
|
$this->telegramService = $telegramService;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->validator = $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(array $data, array $meta = []): void
|
public function create(array $data, array $meta = []): void
|
||||||
{
|
{
|
||||||
$this->validate($data);
|
try {
|
||||||
|
$this->validate($data);
|
||||||
|
} catch (ValidationRuleNotFoundException $e) {
|
||||||
|
throw new RuntimeException($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
$now = date('Y-m-d H:i:s');
|
$now = date('Y-m-d H:i:s');
|
||||||
$storeId = $this->settings->get('oc_store_id');
|
$storeId = $this->settings->get('oc_store_id');
|
||||||
@@ -170,23 +180,22 @@ class OrderCreateService
|
|||||||
$this->sendNotifications($orderData, $data['tgData']);
|
$this->sendNotifications($orderData, $data['tgData']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ValidationRuleNotFoundException
|
||||||
|
*/
|
||||||
private function validate(array $data): void
|
private function validate(array $data): void
|
||||||
{
|
{
|
||||||
$validator = new Validator();
|
$v = $this->validator->make($data, $this->makeValidationRulesFromSettings(), [
|
||||||
|
'firstName' => 'Имя',
|
||||||
$validation = $validator->make($data, [
|
'lastName' => 'Фамилия',
|
||||||
'firstName' => 'required',
|
'email' => 'E-mail',
|
||||||
'lastName' => 'required',
|
'phone' => 'Номер телефона',
|
||||||
'email' => 'required|email',
|
'address' => 'Адрес доставки',
|
||||||
'phone' => 'required',
|
'comment' => 'Комментарий',
|
||||||
'address' => 'required',
|
|
||||||
'comment' => 'required',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$validation->validate();
|
if ($v->fails()) {
|
||||||
|
throw new OrderValidationFailedException($v->getErrors());
|
||||||
if ($validation->fails()) {
|
|
||||||
throw new OrderValidationFailedException($validation->errors());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,4 +241,16 @@ class OrderCreateService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function makeValidationRulesFromSettings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'firstName' => 'required',
|
||||||
|
'lastName' => 'required',
|
||||||
|
'email' => 'required|email',
|
||||||
|
'phone' => 'required',
|
||||||
|
'address' => 'required',
|
||||||
|
'comment' => 'required',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'config_timezone' => 'UTC',
|
'config_timezone' => 'UTC',
|
||||||
|
|
||||||
'lang' => 'en-gb',
|
'lang' => 'en-gb',
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
use Openguru\OpenCartFramework\Application;
|
||||||
|
|
||||||
|
class TestCase extends \PHPUnit\Framework\TestCase
|
||||||
|
{
|
||||||
|
protected Application $app;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$config = [];
|
||||||
|
|
||||||
|
$this->app = new Application($config);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Validator;
|
||||||
|
|
||||||
|
use Openguru\OpenCartFramework\Validator\ErrorBag;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class ErrorBagTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testFirstOfAll(): void
|
||||||
|
{
|
||||||
|
$errorBag = new ErrorBag([
|
||||||
|
'foo' => ['one', 'two'],
|
||||||
|
'bar' => ['three', 'four'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'foo' => 'one',
|
||||||
|
'bar' => 'three',
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $errorBag->firstOfAll());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Validator;
|
||||||
|
|
||||||
|
use Openguru\OpenCartFramework\Validator\ValidationRuleNotFoundException;
|
||||||
|
use Openguru\OpenCartFramework\Validator\ValidationRules\Required;
|
||||||
|
use Openguru\OpenCartFramework\Validator\Validator;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @coversDefaultClass Validator
|
||||||
|
*/
|
||||||
|
class ValidatorTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers Validator::fails()
|
||||||
|
* @covers Validator::make()
|
||||||
|
*/
|
||||||
|
public function testValidateBasic(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator();
|
||||||
|
$this->assertFalse($validator->make([], [])->fails());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Validator::fails()
|
||||||
|
*/
|
||||||
|
public function testThrowExceptionIfRuleNotFound(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator();
|
||||||
|
$v = $validator->make([], [
|
||||||
|
'field' => 'not_exists_rule',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->expectException(ValidationRuleNotFoundException::class);
|
||||||
|
|
||||||
|
$v->fails();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequiredForNonExistentField(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['xyz' => 'abc'], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertTrue($v->fails());
|
||||||
|
$this->assertEquals(1, $v->getErrors()->count());
|
||||||
|
$this->assertEquals(['foo is required'], $v->getErrors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequiredForEmptyField(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => ''], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertTrue($v->fails());
|
||||||
|
$this->assertEquals(1, $v->getErrors()->count());
|
||||||
|
$this->assertEquals(['foo is required'], $v->getErrors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequiredForFalseValue(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => false], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertFalse($v->fails());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequiredForNullValue(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => null], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertTrue($v->fails());
|
||||||
|
$this->assertEquals(1, $v->getErrors()->count());
|
||||||
|
$this->assertEquals(['foo is required'], $v->getErrors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequiredForZero(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => 0], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertFalse($v->fails());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequiredForZeroString(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => "0"], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertFalse($v->fails());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCustomValidationMessages(): void
|
||||||
|
{
|
||||||
|
$customMessages = [
|
||||||
|
'required' => ':field is very required',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
], $customMessages);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => ''], ['foo' => 'required']);
|
||||||
|
|
||||||
|
$this->assertTrue($v->fails());
|
||||||
|
$this->assertEquals(1, $v->getErrors()->count());
|
||||||
|
$this->assertEquals(['foo is very required'], $v->getErrors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCustomFieldNames(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator([
|
||||||
|
'required' => fn () => new Required(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$v = $validator->make(['foo' => ''], [
|
||||||
|
'foo' => 'required'
|
||||||
|
], [
|
||||||
|
'foo' => 'My Field'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertTrue($v->fails());
|
||||||
|
$this->assertEquals(1, $v->getErrors()->count());
|
||||||
|
$this->assertEquals(['My Field is required'], $v->getErrors()->first());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user