Просмотр файла app/Classes/Validator.php

Размер файла: 12.66Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Classes;
  6.  
  7. use Illuminate\Http\UploadedFile;
  8.  
  9. /**
  10. * Class Validation data
  11. *
  12. * @license Code and contributions have MIT License
  13. * @link https://visavi.net
  14. * @author Alexander Grigorev <admin@visavi.net>
  15. */
  16. class Validator
  17. {
  18. /**
  19. * @var array validation errors
  20. */
  21. private $errors = [];
  22.  
  23. /**
  24. * Проверяет длину строки
  25. *
  26. * @param mixed $input
  27. * @param int $min
  28. * @param int $max
  29. * @param mixed $label
  30. * @param bool $required
  31. *
  32. * @return Validator
  33. */
  34. public function length($input, int $min, int $max, $label, bool $required = true): Validator
  35. {
  36. if (! $required && $this->isBlank($input)) {
  37. return $this;
  38. }
  39.  
  40. $input = (string) $input;
  41.  
  42. if (mb_strlen(trim($input), 'utf-8') < $min) {
  43. $this->addError($label, __('validator.length_min', ['length' => $min]));
  44. } elseif (mb_strlen($input, 'utf-8') > $max) {
  45. $this->addError($label, __('validator.length_max', ['length' => $max]));
  46. }
  47.  
  48. return $this;
  49. }
  50.  
  51. /**
  52. * Проверяет число на вхождение в диапазон
  53. *
  54. * @param int|float $input
  55. * @param int|float $min
  56. * @param int|float $max
  57. * @param mixed $label
  58. *
  59. * @return Validator
  60. */
  61. public function between($input, $min, $max, $label): Validator
  62. {
  63. if ($input < $min || $input > $max) {
  64. $this->addError($label, __('validator.between', ['min' => $min, 'max' => $max]));
  65. }
  66.  
  67. return $this;
  68. }
  69.  
  70. /**
  71. * Проверяет на больше чем число
  72. *
  73. * @param int|float $input
  74. * @param int|float $input2
  75. * @param mixed $label
  76. *
  77. * @return Validator
  78. */
  79. public function gt($input, $input2, $label): Validator
  80. {
  81. if ($input <= $input2) {
  82. $this->addError($label);
  83. }
  84.  
  85. return $this;
  86. }
  87.  
  88. /**
  89. * Проверяет на больше чем или равно
  90. *
  91. * @param int|float $input
  92. * @param int|float $input2
  93. * @param mixed $label
  94. *
  95. * @return Validator
  96. */
  97. public function gte($input, $input2, $label): Validator
  98. {
  99. if ($input < $input2) {
  100. $this->addError($label);
  101. }
  102.  
  103. return $this;
  104. }
  105.  
  106. /**
  107. * Проверяет на меньше чем число
  108. *
  109. * @param int|float $input
  110. * @param int|float $input2
  111. * @param mixed $label
  112. *
  113. * @return Validator
  114. */
  115. public function lt($input, $input2, $label): Validator
  116. {
  117. if ($input >= $input2) {
  118. $this->addError($label);
  119. }
  120.  
  121. return $this;
  122. }
  123.  
  124. /**
  125. * Проверяет на меньше чем или равно
  126. *
  127. * @param int|float $input
  128. * @param int|float $input2
  129. * @param mixed $label
  130. *
  131. * @return Validator
  132. */
  133. public function lte($input, $input2, $label): Validator
  134. {
  135. if ($input > $input2) {
  136. $this->addError($label);
  137. }
  138.  
  139. return $this;
  140. }
  141.  
  142. /**
  143. * Проверяет эквивалентны ли данные
  144. *
  145. * @param mixed $input
  146. * @param mixed $input2
  147. * @param mixed $label
  148. *
  149. * @return Validator
  150. */
  151. public function equal($input, $input2, $label): Validator
  152. {
  153. if ($input !== $input2) {
  154. $this->addError($label);
  155. }
  156.  
  157. return $this;
  158. }
  159.  
  160. /**
  161. * Проверяет не эквивалентны ли данные
  162. *
  163. * @param mixed $input
  164. * @param mixed $input2
  165. * @param mixed $label
  166. *
  167. * @return Validator
  168. */
  169. public function notEqual($input, $input2, $label): Validator
  170. {
  171. if ($input === $input2) {
  172. $this->addError($label);
  173. }
  174.  
  175. return $this;
  176. }
  177.  
  178. /**
  179. * Проверяет пустые ли данные
  180. *
  181. * @param mixed $input
  182. * @param mixed $label
  183. *
  184. * @return Validator
  185. */
  186. public function empty($input, $label): Validator
  187. {
  188. if (! empty($input)) {
  189. $this->addError($label);
  190. }
  191.  
  192. return $this;
  193. }
  194.  
  195. /**
  196. * Проверяет не пустые ли данные
  197. *
  198. * @param mixed $input
  199. * @param mixed $label
  200. *
  201. * @return Validator
  202. */
  203. public function notEmpty($input, $label): Validator
  204. {
  205. if (empty($input)) {
  206. $this->addError($label);
  207. }
  208.  
  209. return $this;
  210. }
  211.  
  212. /**
  213. * Проверяет на true
  214. *
  215. * @param mixed $input
  216. * @param mixed $label
  217. *
  218. * @return Validator
  219. */
  220. public function true($input, $label): Validator
  221. {
  222. if (filter_var($input, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === false) {
  223. $this->addError($label);
  224. }
  225.  
  226. return $this;
  227. }
  228.  
  229. /**
  230. * Проверяет на false
  231. *
  232. * @param mixed $input
  233. * @param mixed $label
  234. *
  235. * @return Validator
  236. */
  237. public function false($input, $label): Validator
  238. {
  239. if (filter_var($input, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== false) {
  240. $this->addError($label);
  241. }
  242.  
  243. return $this;
  244. }
  245.  
  246. /**
  247. * Проверяет на вхождение в массив
  248. *
  249. * @param mixed $input
  250. * @param array $haystack
  251. * @param mixed $label
  252. *
  253. * @return Validator
  254. */
  255. public function in($input, array $haystack, $label): Validator
  256. {
  257. if (! is_array($haystack) || ! in_array($input, $haystack, true)) {
  258. $this->addError($label);
  259. }
  260.  
  261. return $this;
  262. }
  263.  
  264. /**
  265. * Проверяет на не вхождение в массив
  266. *
  267. * @param mixed $input
  268. * @param array $haystack
  269. * @param mixed $label
  270. *
  271. * @return Validator
  272. */
  273. public function notIn($input, array $haystack, $label): Validator
  274. {
  275. if (! is_array($haystack) || in_array($input, $haystack, true)) {
  276. $this->addError($label);
  277. }
  278.  
  279. return $this;
  280. }
  281.  
  282. /**
  283. * Проверяет по регулярному выражению
  284. *
  285. * @param mixed $input
  286. * @param string $pattern
  287. * @param mixed $label
  288. * @param bool $required
  289. *
  290. * @return Validator
  291. */
  292. public function regex($input, string $pattern, $label, bool $required = true): Validator
  293. {
  294. if (! $required && $this->isBlank($input)) {
  295. return $this;
  296. }
  297.  
  298. if (! preg_match($pattern, $input)) {
  299. $this->addError($label);
  300. }
  301.  
  302. return $this;
  303. }
  304.  
  305. /**
  306. * Check float
  307. *
  308. * @param mixed $input
  309. * @param mixed $label
  310. * @param bool $required
  311. *
  312. * @return Validator
  313. */
  314. public function float($input, $label, bool $required = true): Validator
  315. {
  316. if (! $required && $this->isBlank($input)) {
  317. return $this;
  318. }
  319.  
  320. if (! is_float($input)) {
  321. $this->addError($label);
  322. }
  323.  
  324. return $this;
  325. }
  326.  
  327. /**
  328. * Проверяет адрес сайта
  329. *
  330. * @param mixed $input
  331. * @param mixed $label
  332. * @param bool $required
  333. *
  334. * @return Validator
  335. */
  336. public function url($input, $label, bool $required = true): Validator
  337. {
  338. if (! $required && $this->isBlank($input)) {
  339. return $this;
  340. }
  341.  
  342. if (! preg_match('|^https?://([а-яa-z0-9_\-\.])+(\.([а-яa-z0-9\/\-?_=#])+)+$|iu', $input)) {
  343. $this->addError($label);
  344. }
  345.  
  346. return $this;
  347. }
  348.  
  349. /**
  350. * Проверяет email
  351. *
  352. * @param mixed $input
  353. * @param mixed $label
  354. * @param bool $required
  355. *
  356. * @return Validator
  357. */
  358. public function email($input, $label, bool $required = true): Validator
  359. {
  360. if (! $required && $this->isBlank($input)) {
  361. return $this;
  362. }
  363.  
  364. if (filter_var($input, FILTER_VALIDATE_EMAIL) === false) {
  365. $this->addError($label);
  366. }
  367.  
  368. return $this;
  369. }
  370.  
  371. /**
  372. * Check IP address
  373. *
  374. * @param mixed $input
  375. * @param mixed $label
  376. * @param bool $required
  377. *
  378. * @return Validator
  379. */
  380. public function ip($input, $label, bool $required = true): Validator
  381. {
  382. if (! $required && $this->isBlank($input)) {
  383. return $this;
  384. }
  385.  
  386. if (filter_var($input, FILTER_VALIDATE_IP) === false) {
  387. $this->addError($label);
  388. }
  389.  
  390. return $this;
  391. }
  392.  
  393. /**
  394. * Check phone
  395. *
  396. * @param mixed $input
  397. * @param mixed $label
  398. * @param bool $required
  399. *
  400. * @return Validator
  401. */
  402. public function phone($input, $label, bool $required = true): Validator
  403. {
  404. if (! $required && $this->isBlank($input)) {
  405. return $this;
  406. }
  407.  
  408. if (! preg_match('#^\d{8,13}$#', $input)) {
  409. $this->addError($label);
  410. }
  411.  
  412. return $this;
  413. }
  414.  
  415. /**
  416. * Проверяет файл
  417. *
  418. * @param UploadedFile|null $input
  419. * @param array $rules
  420. * @param mixed $label
  421. * @param bool $required
  422. *
  423. * @return Validator
  424. */
  425. public function file(?UploadedFile $input, array $rules, $label, bool $required = true): Validator
  426. {
  427. if (! $required && $this->isBlank($input)) {
  428. return $this;
  429. }
  430.  
  431. if (! $input instanceof UploadedFile) {
  432. $this->addError($label);
  433. return $this;
  434. }
  435.  
  436. if (! $input->isValid()) {
  437. $this->addError($input->getErrorMessage());
  438. return $this;
  439. }
  440.  
  441. $key = is_array($label) ? key($label) : 0;
  442.  
  443. if (empty($rules['extensions'])) {
  444. $rules['extensions'] = ['jpg', 'jpeg', 'gif', 'png'];
  445. }
  446.  
  447. $extension = strtolower($input->getClientOriginalExtension());
  448.  
  449. if (! in_array($extension, $rules['extensions'], true)) {
  450. $this->addError([$key => __('validator.extension')]);
  451. }
  452.  
  453. if (isset($rules['maxsize']) && $input->getSize() > $rules['maxsize']) {
  454. $this->addError([$key => __('validator.size_max', ['size' => formatSize($rules['maxsize'])])]);
  455. }
  456.  
  457. if (in_array($extension, ['jpg', 'jpeg', 'gif', 'png'], true)) {
  458. [$width, $height] = getimagesize($input->getPathname());
  459.  
  460. if (isset($rules['maxweight'])) {
  461. if ($width > $rules['maxweight'] || $height > $rules['maxweight']) {
  462. $this->addError([$key => __('validator.weight_max', ['weight' => $rules['maxweight']])]);
  463. }
  464. }
  465.  
  466. if (isset($rules['minweight'])) {
  467. if ($width < $rules['minweight'] || $height < $rules['minweight']) {
  468. $this->addError([$key => __('validator.weight_min', ['weight' => $rules['minweight']])]);
  469. }
  470. } elseif (empty($width) || empty($height)) {
  471. $this->addError([$key => __('validator.weight_empty')]);
  472. }
  473. }
  474.  
  475. return $this;
  476. }
  477.  
  478. /**
  479. * Добавляет ошибки в массив
  480. *
  481. * @param mixed $error текст ошибки
  482. * @param string|null $description
  483. *
  484. * @return void
  485. */
  486. public function addError($error, $description = null): void
  487. {
  488. $key = 0;
  489.  
  490. if (is_array($error)) {
  491. $key = key($error);
  492. $error = current($error);
  493. }
  494.  
  495. if (isset($this->errors[$key])) {
  496. $this->errors[] = trim($error . ' ' . $description);
  497. } else {
  498. $this->errors[$key] = trim($error . ' ' . $description);
  499. }
  500. }
  501.  
  502. /**
  503. * Возвращает список ошибок
  504. *
  505. * @return array
  506. */
  507. public function getErrors(): array
  508. {
  509. return $this->errors;
  510. }
  511.  
  512. /**
  513. * Очищает список ошибок
  514. *
  515. * @return void
  516. */
  517. public function clearErrors(): void
  518. {
  519. $this->errors = [];
  520. }
  521.  
  522. /**
  523. * Возвращает успешность валидации
  524. *
  525. * @return bool
  526. */
  527. public function isValid(): bool
  528. {
  529. return empty($this->errors);
  530. }
  531.  
  532. /**
  533. * Is blank
  534. *
  535. * @param mixed $value
  536. *
  537. * @return bool
  538. */
  539. private function isBlank($value): bool
  540. {
  541. if (is_null($value)) {
  542. return true;
  543. }
  544.  
  545. if (is_string($value)) {
  546. return $value === '';
  547. }
  548.  
  549. if (is_numeric($value) || is_bool($value)) {
  550. return false;
  551. }
  552.  
  553. return empty($value);
  554. }
  555. }