Loading config/services.yaml +3 −0 Original line number Diff line number Diff line Loading @@ -22,3 +22,6 @@ services: # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones App\Service\FileUploader: arguments: $targetDirectory: '%kernel.project_dir%/public/files/' No newline at end of file src/Action/Functions.php +3 −61 Original line number Diff line number Diff line Loading @@ -4,11 +4,11 @@ declare(strict_types=1); namespace App\Action; use Exception; use DateTimeImmutable; use DateTime; use DateInterval; use DatePeriod; use Exception; use DateInterval; class Functions { Loading @@ -17,7 +17,6 @@ class Functions * @param array $array * @return array */ public function sortPrice(array $array): array { $prices = array_column($array, 'price'); Loading @@ -31,13 +30,6 @@ class Functions return $array; } /** * На выход должна вернуть отсортированный массив по ключу *price* DESC * и во вторую очередь по *count* ASC: * [['price'=>12, 'count'=>4], ['price'=>10, 'count'=>2], ['price'=>8, 'count'=>4], * ['price'=>8, 'count'=>5], ['price'=>5, 'count'=>5],] */ /** * Найдет элемент с указаным id * @param array $array - массив, содержащий элементы со структурой Loading @@ -64,21 +56,11 @@ class Functions * @param array $array * @return array */ public function uniqElements(array $array): array { return array_unique($array, SORT_REGULAR); } /** * Выходной массив: * Array ( * [0] => Array([0] => laravel, [1] => php) * [1] => Array([0] => codeigniter, [1] => php) * [3] => Array([0] => c++, [1] => java)) * ) */ /** * Сгруппировать подразедлы в верхние разделы меню * Дочерние элементы поместить в массив родителя с ключом submenu Loading @@ -89,7 +71,6 @@ class Functions * @param array $aMenu * @return array */ public function prepareMenu(array $aMenu): array { $result = []; Loading @@ -110,47 +91,12 @@ class Functions return $result; } /** * Выходные данные: * $aMenu = [ * [ * 'name' => 'Смартфоны и гаджеты', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Смартфоны, мобильные телефоны','depth' => 1,], * ['name' => 'Планшеты','depth' => 1,], * ['name' => 'Наушники и гарнитуры','depth' => 1,],], * ], * [ * 'name' => 'Компьютеры и ноутбуки', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Ноутбуки и аксессуары','depth' => 1,], * ['name' => 'Компьютеры и мониторы','depth' => 1,], * ['name' => 'Компьютерные комплектующие','depth' => 1,],]], * [ * 'name' => 'Техника для дома', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Техника для уборки','depth' => 1,], * ['name' => 'Товары для ухода за одеждой','depth' => 1,], * ['name' => 'Аксессуары для техники','depth' => 1,],] * ], * [ * 'name' => 'Товары для дома и кухни', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Посуда','depth' => 1,],]], * ]; */ /** * Функция рассчитывает кол-во дней до нового года * @param DateTimeImmutable $date дата от которой, необходимо рассчитать кол-во дней * @return int * @throws Exception */ public function howDaysToNy(DateTimeImmutable $date): int { $endYear = date("Y-12-31", date_timestamp_get($date)); Loading @@ -164,7 +110,6 @@ class Functions * @return DateTimeImmutable[] * @throws Exception */ public function countFriday13(int $year): iterable { $startDate = new DateTime("$year-01-01 Friday"); Loading Loading @@ -196,7 +141,6 @@ class Functions * @return string * @throws RuntimeException */ public function readLogFile(string $filePath): string { if (file_exists($filePath)) { Loading @@ -209,10 +153,8 @@ class Functions fclose($file); return $text; } else { throw new RuntimeException("File not found: $filePath"); } } /** * Переделай своё решение 8 задачи: Loading src/Controller/HomeController.php +46 −57 Original line number Diff line number Diff line Loading @@ -3,80 +3,71 @@ namespace App\Controller; use App\Action\Functions; use App\Validation\{ArrayValidation, DateValidation}; use App\Requests\{ SortPriceRequest, SearchRequest, UniqElementsRequest, MenuRequest, HowDaysToNyRequest, CountFriday13Request, DiffDaysRequest }; use DateTimeImmutable; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class HomeController extends AbstractController { private Functions $functions; public function __construct(Functions $functions) { $this->functions = $functions; } public function __construct(private Functions $functions) {} #[Route('/func1', name: 'home', methods: ['POST'])] public function func1(Request $request): Response #[Route('/sortPrice', name: 'sortPrice', methods: ['POST'])] public function sortPrice(SortPriceRequest $request): Response { $array = $request->get('arr'); if (!ArrayValidation::validateFunc1($array)) { return new Response("Invalid array"); } $array = $this->functions->sortPrice($array); $array = $this->functions->sortPrice($request->getRequest()->toArray()['items']); return $this->json($array); } #[Route('/func2', name: 'func2', methods: ['POST'])] public function func2(Request $request): Response #[Route('/search', name: 'search', methods: ['POST'])] public function search(SearchRequest $request): Response { $id = $request->query->getInt('id'); $array = $request->get('arr'); if (!ArrayValidation::validateFunc2($array)) { return new Response("Invalid array"); } $array = $request->getRequest()->toArray()['items']; $id = $request->getRequest()->query->get('id'); $result = $this->functions->search($array, $id); return $this->json($result); } #[Route('/func3', name: 'func3', methods: ['POST'])] public function home(Request $request): Response #[Route('/uniqElements', name: 'uniqElements', methods: ['POST'])] public function uniqElements(UniqElementsRequest $request): Response { $array = $request->get('arr'); $result = $this->functions->uniqElements($array); $result = $this->functions->uniqElements($request->getRequest()->toArray()['items']); return $this->json($result); } #[Route('/func4', name: 'func4', methods: ['POST'])] public function func4(Request $request): Response #[Route('/prepareMenu', name: 'prepareMenu', methods: ['POST'])] public function prepareMenu(MenuRequest $request): Response { $array = $request->get('arr'); if (!ArrayValidation::validateFunc4($array)) { return new Response("Invalid array"); } $result = $this->functions->prepareMenu($array); $result = $this->functions->prepareMenu($request->getRequest()->toArray()['items']); return $this->json($result); } #[Route('/func5/{day}/{month}/{year}', name: 'func5')] public function func5(int $day, int $month, int $year): Response #[Route('/howDaysToNy', name: 'howDaysToNy', methods: ['GET'])] public function howDaysToNy(HowDaysToNyRequest $request): Response { $dateAsString = $year . "-" . $month . "-" . $day; $date = $request->getRequest()->get('date'); try { $result = $this->functions->howDaysToNy(new DateTimeImmutable($dateAsString)); $result = $this->functions->howDaysToNy(new DateTimeImmutable($date)); } catch (\Exception $e) { return new Response($e->getMessage()); } return $this->json(["Days before NY:" => $result]); } #[Route('/func6/{year}', name: 'func6', methods: ['GET'])] public function func6(int $year): Response #[Route('/countFriday13', name: 'countFriday13', methods: ['GET'])] public function countFriday13(CountFriday13Request $request): Response { $year = $request->getRequest()->get('year'); $fridays = array(); try { foreach ($this->functions->countFriday13($year) as $date) { Loading @@ -88,28 +79,26 @@ class HomeController extends AbstractController return $this->json($fridays); } #[Route('/func7/{startDate}/{endDate}', name: 'func7')] // 01-01-2024 public function func7(string $startDate, string $endDate): Response #[Route('/diffDays', name: 'diffDays')] // 01-01-2024 public function diffDays(DiffDaysRequest $request): Response { if (DateValidation::validate($startDate) && DateValidation::validate($endDate)) { try { $result = $this->functions->diffDays( new DateTimeImmutable($startDate), new DateTimeImmutable($endDate) new DateTimeImmutable($request->getRequest()->get('startDate')), new DateTimeImmutable($request->getRequest()->get('endDate')), ); return $this->json(["The difference of days:" => $result]); } catch (\Exception $e) { return new Response($e->getMessage()); } } return new Response("Invalid date format"); } #[Route('/func8/{fileName}', name: 'func8')] public function func8(string $fileName): Response // text.txt #[Route('/readLogFile', name: 'readLogFile')] public function readLogFile(Request $request, FileUploader $fileUploader): Response { $filePath = $this->getParameter('kernel.project_dir') . "/public/files/"; $text = $this->functions->readLogFile($filePath . $fileName); $file = $request->files->get('file'); $fileName = $fileUploader->upload($file); $text = $this->functions->readLogFile($fileName); $response = new JsonResponse($text); $response->setEncodingOptions(JSON_UNESCAPED_UNICODE); return $response; Loading src/Requests/BaseRequest.php 0 → 100644 +62 −0 Original line number Diff line number Diff line <?php namespace App\Requests; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\Validator\ValidatorInterface; abstract class BaseRequest { public function __construct(protected ValidatorInterface $validator) { $this->populate(); if ($this->autoValidateRequest()) { $this->validate(); } } public function validate(): void { $errors = $this->validator->validate($this); $messages = ['message' => 'validation_failed', 'errors' => []]; /** @var ConstraintViolation $errors */ foreach ($errors as $message) { $messages['errors'][] = [ 'property' => $message->getPropertyPath(), 'value' => $message->getInvalidValue(), 'message' => $message->getMessage(), ]; } if (count($messages['errors']) > 0) { $response = new JsonResponse($messages, 201); $response->send(); exit; } } public function getRequest(): Request { return Request::createFromGlobals(); } protected function populate(): void { foreach ($this->getRequest()->request->all() as $property => $value) { if (property_exists($this, $property)) { $this->{$property} = $value; } } } protected function autoValidateRequest(): bool { return true; } } No newline at end of file src/Requests/CountFriday13Request.php 0 → 100644 +21 −0 Original line number Diff line number Diff line <?php namespace App\Requests; use Symfony\Component\Validator\Constraints as Assert; class CountFriday13Request extends BaseRequest { #[Assert\Type('int')] #[Assert\Positive] public int $year; protected function populate(): void { foreach ($this->getRequest()->query->all() as $property => $value) { if (property_exists($this, $property)) { $this->{$property} = $value; } } } } No newline at end of file Loading
config/services.yaml +3 −0 Original line number Diff line number Diff line Loading @@ -22,3 +22,6 @@ services: # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones App\Service\FileUploader: arguments: $targetDirectory: '%kernel.project_dir%/public/files/' No newline at end of file
src/Action/Functions.php +3 −61 Original line number Diff line number Diff line Loading @@ -4,11 +4,11 @@ declare(strict_types=1); namespace App\Action; use Exception; use DateTimeImmutable; use DateTime; use DateInterval; use DatePeriod; use Exception; use DateInterval; class Functions { Loading @@ -17,7 +17,6 @@ class Functions * @param array $array * @return array */ public function sortPrice(array $array): array { $prices = array_column($array, 'price'); Loading @@ -31,13 +30,6 @@ class Functions return $array; } /** * На выход должна вернуть отсортированный массив по ключу *price* DESC * и во вторую очередь по *count* ASC: * [['price'=>12, 'count'=>4], ['price'=>10, 'count'=>2], ['price'=>8, 'count'=>4], * ['price'=>8, 'count'=>5], ['price'=>5, 'count'=>5],] */ /** * Найдет элемент с указаным id * @param array $array - массив, содержащий элементы со структурой Loading @@ -64,21 +56,11 @@ class Functions * @param array $array * @return array */ public function uniqElements(array $array): array { return array_unique($array, SORT_REGULAR); } /** * Выходной массив: * Array ( * [0] => Array([0] => laravel, [1] => php) * [1] => Array([0] => codeigniter, [1] => php) * [3] => Array([0] => c++, [1] => java)) * ) */ /** * Сгруппировать подразедлы в верхние разделы меню * Дочерние элементы поместить в массив родителя с ключом submenu Loading @@ -89,7 +71,6 @@ class Functions * @param array $aMenu * @return array */ public function prepareMenu(array $aMenu): array { $result = []; Loading @@ -110,47 +91,12 @@ class Functions return $result; } /** * Выходные данные: * $aMenu = [ * [ * 'name' => 'Смартфоны и гаджеты', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Смартфоны, мобильные телефоны','depth' => 1,], * ['name' => 'Планшеты','depth' => 1,], * ['name' => 'Наушники и гарнитуры','depth' => 1,],], * ], * [ * 'name' => 'Компьютеры и ноутбуки', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Ноутбуки и аксессуары','depth' => 1,], * ['name' => 'Компьютеры и мониторы','depth' => 1,], * ['name' => 'Компьютерные комплектующие','depth' => 1,],]], * [ * 'name' => 'Техника для дома', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Техника для уборки','depth' => 1,], * ['name' => 'Товары для ухода за одеждой','depth' => 1,], * ['name' => 'Аксессуары для техники','depth' => 1,],] * ], * [ * 'name' => 'Товары для дома и кухни', * 'depth' => 0, * 'submenu' => [ * ['name' => 'Посуда','depth' => 1,],]], * ]; */ /** * Функция рассчитывает кол-во дней до нового года * @param DateTimeImmutable $date дата от которой, необходимо рассчитать кол-во дней * @return int * @throws Exception */ public function howDaysToNy(DateTimeImmutable $date): int { $endYear = date("Y-12-31", date_timestamp_get($date)); Loading @@ -164,7 +110,6 @@ class Functions * @return DateTimeImmutable[] * @throws Exception */ public function countFriday13(int $year): iterable { $startDate = new DateTime("$year-01-01 Friday"); Loading Loading @@ -196,7 +141,6 @@ class Functions * @return string * @throws RuntimeException */ public function readLogFile(string $filePath): string { if (file_exists($filePath)) { Loading @@ -209,10 +153,8 @@ class Functions fclose($file); return $text; } else { throw new RuntimeException("File not found: $filePath"); } } /** * Переделай своё решение 8 задачи: Loading
src/Controller/HomeController.php +46 −57 Original line number Diff line number Diff line Loading @@ -3,80 +3,71 @@ namespace App\Controller; use App\Action\Functions; use App\Validation\{ArrayValidation, DateValidation}; use App\Requests\{ SortPriceRequest, SearchRequest, UniqElementsRequest, MenuRequest, HowDaysToNyRequest, CountFriday13Request, DiffDaysRequest }; use DateTimeImmutable; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class HomeController extends AbstractController { private Functions $functions; public function __construct(Functions $functions) { $this->functions = $functions; } public function __construct(private Functions $functions) {} #[Route('/func1', name: 'home', methods: ['POST'])] public function func1(Request $request): Response #[Route('/sortPrice', name: 'sortPrice', methods: ['POST'])] public function sortPrice(SortPriceRequest $request): Response { $array = $request->get('arr'); if (!ArrayValidation::validateFunc1($array)) { return new Response("Invalid array"); } $array = $this->functions->sortPrice($array); $array = $this->functions->sortPrice($request->getRequest()->toArray()['items']); return $this->json($array); } #[Route('/func2', name: 'func2', methods: ['POST'])] public function func2(Request $request): Response #[Route('/search', name: 'search', methods: ['POST'])] public function search(SearchRequest $request): Response { $id = $request->query->getInt('id'); $array = $request->get('arr'); if (!ArrayValidation::validateFunc2($array)) { return new Response("Invalid array"); } $array = $request->getRequest()->toArray()['items']; $id = $request->getRequest()->query->get('id'); $result = $this->functions->search($array, $id); return $this->json($result); } #[Route('/func3', name: 'func3', methods: ['POST'])] public function home(Request $request): Response #[Route('/uniqElements', name: 'uniqElements', methods: ['POST'])] public function uniqElements(UniqElementsRequest $request): Response { $array = $request->get('arr'); $result = $this->functions->uniqElements($array); $result = $this->functions->uniqElements($request->getRequest()->toArray()['items']); return $this->json($result); } #[Route('/func4', name: 'func4', methods: ['POST'])] public function func4(Request $request): Response #[Route('/prepareMenu', name: 'prepareMenu', methods: ['POST'])] public function prepareMenu(MenuRequest $request): Response { $array = $request->get('arr'); if (!ArrayValidation::validateFunc4($array)) { return new Response("Invalid array"); } $result = $this->functions->prepareMenu($array); $result = $this->functions->prepareMenu($request->getRequest()->toArray()['items']); return $this->json($result); } #[Route('/func5/{day}/{month}/{year}', name: 'func5')] public function func5(int $day, int $month, int $year): Response #[Route('/howDaysToNy', name: 'howDaysToNy', methods: ['GET'])] public function howDaysToNy(HowDaysToNyRequest $request): Response { $dateAsString = $year . "-" . $month . "-" . $day; $date = $request->getRequest()->get('date'); try { $result = $this->functions->howDaysToNy(new DateTimeImmutable($dateAsString)); $result = $this->functions->howDaysToNy(new DateTimeImmutable($date)); } catch (\Exception $e) { return new Response($e->getMessage()); } return $this->json(["Days before NY:" => $result]); } #[Route('/func6/{year}', name: 'func6', methods: ['GET'])] public function func6(int $year): Response #[Route('/countFriday13', name: 'countFriday13', methods: ['GET'])] public function countFriday13(CountFriday13Request $request): Response { $year = $request->getRequest()->get('year'); $fridays = array(); try { foreach ($this->functions->countFriday13($year) as $date) { Loading @@ -88,28 +79,26 @@ class HomeController extends AbstractController return $this->json($fridays); } #[Route('/func7/{startDate}/{endDate}', name: 'func7')] // 01-01-2024 public function func7(string $startDate, string $endDate): Response #[Route('/diffDays', name: 'diffDays')] // 01-01-2024 public function diffDays(DiffDaysRequest $request): Response { if (DateValidation::validate($startDate) && DateValidation::validate($endDate)) { try { $result = $this->functions->diffDays( new DateTimeImmutable($startDate), new DateTimeImmutable($endDate) new DateTimeImmutable($request->getRequest()->get('startDate')), new DateTimeImmutable($request->getRequest()->get('endDate')), ); return $this->json(["The difference of days:" => $result]); } catch (\Exception $e) { return new Response($e->getMessage()); } } return new Response("Invalid date format"); } #[Route('/func8/{fileName}', name: 'func8')] public function func8(string $fileName): Response // text.txt #[Route('/readLogFile', name: 'readLogFile')] public function readLogFile(Request $request, FileUploader $fileUploader): Response { $filePath = $this->getParameter('kernel.project_dir') . "/public/files/"; $text = $this->functions->readLogFile($filePath . $fileName); $file = $request->files->get('file'); $fileName = $fileUploader->upload($file); $text = $this->functions->readLogFile($fileName); $response = new JsonResponse($text); $response->setEncodingOptions(JSON_UNESCAPED_UNICODE); return $response; Loading
src/Requests/BaseRequest.php 0 → 100644 +62 −0 Original line number Diff line number Diff line <?php namespace App\Requests; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\Validator\ValidatorInterface; abstract class BaseRequest { public function __construct(protected ValidatorInterface $validator) { $this->populate(); if ($this->autoValidateRequest()) { $this->validate(); } } public function validate(): void { $errors = $this->validator->validate($this); $messages = ['message' => 'validation_failed', 'errors' => []]; /** @var ConstraintViolation $errors */ foreach ($errors as $message) { $messages['errors'][] = [ 'property' => $message->getPropertyPath(), 'value' => $message->getInvalidValue(), 'message' => $message->getMessage(), ]; } if (count($messages['errors']) > 0) { $response = new JsonResponse($messages, 201); $response->send(); exit; } } public function getRequest(): Request { return Request::createFromGlobals(); } protected function populate(): void { foreach ($this->getRequest()->request->all() as $property => $value) { if (property_exists($this, $property)) { $this->{$property} = $value; } } } protected function autoValidateRequest(): bool { return true; } } No newline at end of file
src/Requests/CountFriday13Request.php 0 → 100644 +21 −0 Original line number Diff line number Diff line <?php namespace App\Requests; use Symfony\Component\Validator\Constraints as Assert; class CountFriday13Request extends BaseRequest { #[Assert\Type('int')] #[Assert\Positive] public int $year; protected function populate(): void { foreach ($this->getRequest()->query->all() as $property => $value) { if (property_exists($this, $property)) { $this->{$property} = $value; } } } } No newline at end of file