diff --git a/src/Actions/SortPriceAction.php b/src/Actions/SortPriceAction.php index 13d202339227a31c984fa97d578baaa43318a1de..067f67ed9020bbdfacb7f88dfae057eec402b6fc 100644 --- a/src/Actions/SortPriceAction.php +++ b/src/Actions/SortPriceAction.php @@ -2,19 +2,15 @@ namespace App\Actions; -use App\Entity\InterfaceDataEntity; - -class SortPriceAction implements InterfaceAction +class SortPriceAction { /** * ВыполнÑет Ñортировку маÑÑива по убыванию цены - * @param InterfaceDataEntity $model + * @param array $array * @return array отÑортированный */ - public function act(InterfaceDataEntity $model): array + public function act(array $array): array { - $array = $model->prices; - $priceColumn = array_column($array, "price"); $countColumn = array_column($array, "count"); diff --git a/src/Controller/SortPriceController.php b/src/Controller/SortPriceController.php index 417b4612aca35c041b3aa5b1f03f127c247a6a8d..313d3dc8c22d4304111a09bcec01e3a5b1bab5da 100644 --- a/src/Controller/SortPriceController.php +++ b/src/Controller/SortPriceController.php @@ -4,6 +4,7 @@ namespace App\Controller; use App\Actions\SortPriceAction; use App\Entity\PricesEntity; +use App\Requests\PricesRequest; use App\Service\ValidationService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; @@ -19,14 +20,11 @@ class SortPriceController extends AbstractController * @return JsonResponse */ #[Route('/sort/price', name: 'app_sort_price', methods: ['POST'])] - public function index(Request $request, SortPriceAction $action): JsonResponse + public function index(PricesRequest $request, SortPriceAction $action): JsonResponse { - $priceEntity = new PricesEntity(); - $priceEntity->serialise($request); - - $validation = new ValidationService(); - $validation->validate($priceEntity); - - return new JsonResponse($action->act($priceEntity)); + return new JsonResponse( + $action->act($request->serialise()), + 200 + ); } } diff --git a/src/Requests/BaseRequest.php b/src/Requests/BaseRequest.php new file mode 100644 index 0000000000000000000000000000000000000000..b2fb49ed286c374885e1b073732ab13a0366d5a0 --- /dev/null +++ b/src/Requests/BaseRequest.php @@ -0,0 +1,71 @@ +<?php + +namespace App\Requests; + +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Validator\Exception\ValidatorException; +use Symfony\Component\Validator\Validator\ValidatorInterface; + +abstract class BaseRequest +{ + /** + * Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð²Ð°Ð»Ð¸Ð´Ð°Ñ†Ð¸Ð¸ + * перезапиÑать на false Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ автовалидации + */ + protected const AUTO_VALIDATE = true; + + public function __construct(protected ValidatorInterface $validator) + { + $this->populate(); + + if (self::AUTO_VALIDATE) { + $this->validate(); + } + } + + protected function populate(): void + { + foreach ($this->getRequest()->toArray() as $property => $value) { + if (property_exists($this, $property)) { + $this->{$property} = $value; + } + } + } + + /** + * Ð²Ð°Ð»Ð¸Ð´Ð°Ñ†Ð¸Ñ Ð¸ выброкÑа ошибки при валидации + * @return void + */ + public function validate() + { + $errors = $this->validator->validate($this); + + $messages = [ + 'message' => 'validation_failed', + 'errors' => [] + ]; + + foreach ($errors as $error) { + $messages['errors'][] = [ + 'property' => $error->getPropertyPath(), + 'value' => $error->getInvalidValue(), + 'message' => $error->getMessage(), + ]; + } + + if (count($messages['errors']) > 0) { + $response = new JsonResponse($messages, 201); + $response->send(); + + throw new ValidatorException('Validation failed', $messages); + } + } + + public function getRequest(): Request + { + return Request::createFromGlobals(); + } + + abstract public function serialise(): mixed; +} \ No newline at end of file diff --git a/src/Requests/PricesRequest.php b/src/Requests/PricesRequest.php new file mode 100644 index 0000000000000000000000000000000000000000..dadac42991ac8f9fab940eccac3de760d24cbff3 --- /dev/null +++ b/src/Requests/PricesRequest.php @@ -0,0 +1,42 @@ +<?php + +namespace App\Requests; + +use Symfony\Component\Validator\Constraints\All; +use Symfony\Component\Validator\Constraints\Collection; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\Type; +use Symfony\Contracts\Service\Attribute\Required; + +class PricesRequest extends BaseRequest +{ + #[Type('array')] + #[NotBlank()] + #[Required()] + #[All( + constraints: [ + new Collection( + fields: [ + 'price' => [ + new NotBlank(), + new Type('integer'), + ], + 'count' => [ + new NotBlank(), + new Type('integer'), + ], + ], + ) + ] + )] + public $prices; + + /** + * ÑÐµÑ€Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ€ÐµÐºÐ²ÐµÑта под маÑÑив + * @return mixed + */ + public function serialise(): mixed + { + return $this->prices; + } +} diff --git a/templates/id_search/index.html.twig b/templates/id_search/index.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..69a280e448c95e97964807ec52c04cf17bff3994 --- /dev/null +++ b/templates/id_search/index.html.twig @@ -0,0 +1,20 @@ +{% extends 'base.html.twig' %} + +{% block title %}Hello IdSearchController!{% endblock %} + +{% block body %} +<style> + .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } + .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } +</style> + +<div class="example-wrapper"> + <h1>Hello {{ controller_name }}! ✅</h1> + + This friendly message is coming from: + <ul> + <li>Your controller at <code>/home/tamanit/myProj/iqdevTranningProgram/src/Controller/IdSearchController.php</code></li> + <li>Your template at <code>/home/tamanit/myProj/iqdevTranningProgram/templates/id_search/index.html.twig</code></li> + </ul> +</div> +{% endblock %}