From 39659a8598d5a0a3769e657408682ea597a54f35 Mon Sep 17 00:00:00 2001 From: Krzysztof Marczak Date: Mon, 10 Jan 2022 17:48:04 +0100 Subject: [PATCH] Github CI test (#18) ### New features * new github action: php cs ### Improvements * massive code-style fix --- .github/workflows/phpcs.yaml | 20 ++ composer.json | 7 +- composer.lock | 60 +++- dev/phpcs/ruleset.xml | 12 + dev/phpcs/run.sh | 10 + src/Controller/ArchivesController.php | 57 ++-- src/Controller/ClientsController.php | 26 +- src/Controller/IndexController.php | 35 +- src/Controller/InvoicesController.php | 35 +- src/Controller/ReportsController.php | 262 +++++++-------- src/Controller/TaskController.php | 6 +- src/Entity/Order.php | 3 +- src/Entity/Staff.php | 2 +- src/Entity/User.php | 2 +- src/Form/AddOrderForm.php | 10 +- src/Form/AddTaskForm.php | 2 +- src/Form/InvoiceMonthFormType.php | 2 +- src/Kernel.php | 14 +- src/Security/LoginFormAuthenticator.php | 25 +- src/Service/ReportInterface.php | 64 ++-- src/Service/Reports/CertifiedUaPlReport.php | 341 ++++++++++---------- src/Service/ReportsFactory.php | 73 +++-- symfony.lock | 12 + 23 files changed, 615 insertions(+), 465 deletions(-) create mode 100644 .github/workflows/phpcs.yaml create mode 100644 dev/phpcs/ruleset.xml create mode 100755 dev/phpcs/run.sh diff --git a/.github/workflows/phpcs.yaml b/.github/workflows/phpcs.yaml new file mode 100644 index 0000000..c12470a --- /dev/null +++ b/.github/workflows/phpcs.yaml @@ -0,0 +1,20 @@ +name: Analysis +on: pull_request + +jobs: + build: + name: Analysis + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v1 + + - name: PHP CodeSniffer + run: | + composer global require "squizlabs/php_codesniffer=*" \ + --no-interaction --prefer-dist --ignore-platform-reqs --quiet + ~/.composer/vendor/bin/phpcs --config-set colors 1 + ~/.composer/vendor/bin/phpcs \ + --extensions=php \ + --standard=./dev/phpcs/ruleset.xml \ + ./src -s \ No newline at end of file diff --git a/composer.json b/composer.json index cc06f95..0ea2851 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", + "squizlabs/php_codesniffer": "*", "symfony/debug-bundle": "5.2.*" }, "config": { @@ -44,7 +45,11 @@ "preferred-install": { "*": "dist" }, - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "composer/package-versions-deprecated": true, + "symfony/flex": true + } }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 2501595..a7c5b99 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c23633950ef88cb1a71fa4eb69970f64", + "content-hash": "4f9ab5cbb3478d4523ec9a3018998348", "packages": [ { "name": "beberlei/doctrineextensions", @@ -6827,6 +6827,62 @@ }, "time": "2020-10-14T08:32:19+00:00" }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.6.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2021-12-12T21:44:58+00:00" + }, { "name": "symfony/debug-bundle", "version": "v5.2.4", @@ -6981,5 +7037,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.2.0" } diff --git a/dev/phpcs/ruleset.xml b/dev/phpcs/ruleset.xml new file mode 100644 index 0000000..829ac7f --- /dev/null +++ b/dev/phpcs/ruleset.xml @@ -0,0 +1,12 @@ + + + Order Manage rDefault PHP Code Sniffer ruleset. + + + + + + + + + diff --git a/dev/phpcs/run.sh b/dev/phpcs/run.sh new file mode 100755 index 0000000..847fd1a --- /dev/null +++ b/dev/phpcs/run.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +docker-compose exec -u www-data php \ + ./vendor/bin/phpcs --config-set colors 1 + +docker-compose exec -u www-data php \ + ./vendor/bin/phpcs \ + --extensions=php \ + --standard=./dev/phpcs/ruleset.xml \ + ./src -s \ No newline at end of file diff --git a/src/Controller/ArchivesController.php b/src/Controller/ArchivesController.php index 2700fa1..d09ee59 100644 --- a/src/Controller/ArchivesController.php +++ b/src/Controller/ArchivesController.php @@ -7,21 +7,21 @@ use App\Entity\Order; use App\Entity\Staff; use App\Form\ArchivesFiltersForm; -use DateTime; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class ArchivesController extends AbstractController { - private $entityManager; - private $request; + private ?Request $request; - public function __construct(EntityManagerInterface $entityManager, RequestStack $request) - { - $this->entityManager = $entityManager; + public function __construct( + private EntityManagerInterface $entityManager, + RequestStack $request + ) { $this->request = $request->getCurrentRequest(); } @@ -44,9 +44,12 @@ private function loadOrdersTable(): array $repository = $this->entityManager->getRepository(Order::class); $user = $this->getUser(); $preferences = $user->getPreferences(); - $staff = $this->entityManager->getRepository(Staff::class)->findOneBy(['id' => $preferences['archives']['select-staff']]); + //doctrine nie zapisuje obiektów w user->preferences['archives']['select-client'], //więc mapuje na id przy zapisie i na obiekt przy odczycie + $staff = $this->entityManager->getRepository(Staff::class)->findOneBy( + ['id' => $preferences['archives']['select-staff']] + ); $orders = $repository->createQueryBuilder('o'); @@ -66,33 +69,32 @@ private function loadOrdersTable(): array if ($preferences['archives']['select-client']) { $orders = $orders ->andWhere('o.client = :client') - ->setParameter('client', $repository->findOneBy(['id' => $preferences['archives']['select-client']])); + ->setParameter('client', $repository->findOneBy( + ['id' => $preferences['archives']['select-client']] + )); } - //doctrine nie zapisuje obiektów w user->preferences['archives']['select-client'], - //więc mapuje na id przy zapisie i na obiekt przy odczycie $dateType = $preferences['archives']['date-type']; if ($preferences['archives']['date-from']) { - $dateFrom = new Datetime($preferences['archives']['date-from']['date']); + $dateFrom = new \Datetime($preferences['archives']['date-from']['date']); $orders - ->andWhere('o.'.$dateType.' >= :dateFrom') + ->andWhere('o.' . $dateType . ' >= :dateFrom') ->setParameter('dateFrom', $dateFrom); } if ($preferences['archives']['date-to']) { - $dateTo = new Datetime($preferences['archives']['date-to']['date']); + $dateTo = new \Datetime($preferences['archives']['date-to']['date']); $dateTo->setTime(23, 59); $orders - ->andWhere('o.'.$dateType.' <= :dateTo') + ->andWhere('o.' . $dateType . ' <= :dateTo') ->setParameter('dateTo', $dateTo); } $orders = $orders ->setMaxResults(100) ->orderBy('o.deadline', 'ASC') - ->getQuery() - ->getResult(); + ->getQuery(); - return $orders; + return $orders->getResult(); } /** @@ -132,14 +134,19 @@ public function filters(): Response if ($form->isSubmitted() && $form->isValid()) { $preferences = $user->getPreferences(); $preferences['archives'] = $form->getData(); - $preferences['archives']['select-staff'] = $preferences['archives']['select-staff'] ? $preferences['archives']['select-staff']->getId() : null; - $preferences['archives']['select-client'] = $preferences['archives']['select-client'] ? $preferences['archives']['select-client']->getId() : null; + $preferences['archives']['select-staff'] = $preferences['archives']['select-staff'] ? + $preferences['archives']['select-staff']->getId() : null; + $preferences['archives']['select-client'] = $preferences['archives']['select-client'] ? + $preferences['archives']['select-client']->getId() : null; $user->setPreferences($preferences); $this->entityManager->persist($user); $this->entityManager->flush(); } - return new Response('
Zaktualizowano preferencje
', 200); + return new Response( + '
Zaktualizowano preferencje
', + 200 + ); } /** @@ -148,12 +155,18 @@ public function filters(): Response public function restore(Order $order): Response { if (!$order->getDeletedAt()) { - return new Response("
Zlecenie nie jest usunięte
", 406); + return new Response( + "
Zlecenie nie jest usunięte
", + 406 + ); } $order->setDeletedAt(null); $this->entityManager->persist($order); $this->entityManager->flush(); - return new Response("
Zlecenie zostało przywrócone.
", 200); + return new Response( + "
Zlecenie zostało przywrócone.
", + 200 + ); } } diff --git a/src/Controller/ClientsController.php b/src/Controller/ClientsController.php index 827e819..bdb3a82 100644 --- a/src/Controller/ClientsController.php +++ b/src/Controller/ClientsController.php @@ -7,18 +7,19 @@ use App\Form\AddClientForm; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class ClientsController extends AbstractController { - private $entityManager; - private $request; + private ?Request $request; - public function __construct(EntityManagerInterface $entityManager, RequestStack $request) - { - $this->entityManager = $entityManager; + public function __construct( + private EntityManagerInterface $entityManager, + RequestStack $request + ) { $this->request = $request->getCurrentRequest(); } @@ -35,14 +36,13 @@ public function index(): Response private function loadClientsTable(): array { $repository = $this->entityManager->getRepository(Client::class); - $clients = $repository->createQueryBuilder('c'); - $clients = $clients + $clients = $repository + ->createQueryBuilder('c') ->andWhere('c.deletedAt is null') ->orderBy('c.alias', 'ASC') - ->getQuery() - ->getResult(); + ->getQuery(); - return $clients; + return $clients->getResult(); } /** @@ -104,7 +104,11 @@ public function addClient(): Response */ public function details(Client $client): Response { - $logs = $this->entityManager->getRepository(Log::class)->findBy(['client' => $client], ['createdAt' => 'DESC'], 100); + $logs = $this->entityManager->getRepository(Log::class)->findBy( + ['client' => $client], + ['createdAt' => 'DESC'], + 100 + ); return $this->render('clients/details.twig', [ 'client' => $client, diff --git a/src/Controller/IndexController.php b/src/Controller/IndexController.php index 091623a..2148a31 100644 --- a/src/Controller/IndexController.php +++ b/src/Controller/IndexController.php @@ -68,12 +68,14 @@ private function loadOrdersTable() //improvements required $statesString = 'o.state = '; foreach ($states as $s) { - $statesString .= ':'.$s.' or o.state = '; + $statesString .= ':' . $s . ' or o.state = '; } $statesString = substr($statesString, 0, -14); $repo = $this->entityManager->getRepository(Order::class); - $staff = $this->entityManager->getRepository(Staff::class)->findOneBy(['id' => $preferences['index']['select-staff']]); + $staff = $this->entityManager->getRepository(Staff::class)->findOneBy( + ['id' => $preferences['index']['select-staff']] + ); $orders = $repo->createQueryBuilder('o') ->andWhere($statesString); @@ -98,16 +100,16 @@ private function loadOrdersTable() //improvements required $dateType = $preferences['index']['date-type']; if ($preferences['index']['date-from']) { - $dateFrom = new Datetime($preferences['index']['date-from']['date']); + $dateFrom = new \Datetime($preferences['index']['date-from']['date']); $orders - ->andWhere('o.'.$dateType.' >= :dateFrom') + ->andWhere('o.' . $dateType . ' >= :dateFrom') ->setParameter('dateFrom', $dateFrom); } if ($preferences['index']['date-to']) { $dateTo = new Datetime($preferences['index']['date-to']['date']); $dateTo->setTime(23, 59); $orders - ->andWhere('o.'.$dateType.' <= :dateTo') + ->andWhere('o.' . $dateType . ' <= :dateTo') ->setParameter('dateTo', $dateTo); } @@ -116,10 +118,9 @@ private function loadOrdersTable() //improvements required ->andWhere('o.deletedAt is null') ->setMaxResults(100) ->orderBy('o.deadline', 'ASC') - ->getQuery() - ->getResult(); + ->getQuery(); - return $orders; + return $orders->getResult(); } /** @@ -133,8 +134,10 @@ public function indexApiFilters(): Response if ($form->isSubmitted() && $form->isValid()) { $preferences = $user->getPreferences(); $preferences['index'] = $form->getData(); - $preferences['index']['select-staff'] = $preferences['index']['select-staff'] ? $preferences['index']['select-staff']->getId() : null; - $preferences['index']['select-client'] = $preferences['index']['select-client'] ? $preferences['index']['select-client']->getId() : null; + $preferences['index']['select-staff'] = $preferences['index']['select-staff'] ? + $preferences['index']['select-staff']->getId() : null; + $preferences['index']['select-client'] = $preferences['index']['select-client'] ? + $preferences['index']['select-client']->getId() : null; $user->setPreferences($preferences); $this->entityManager->persist($user); $this->entityManager->flush(); @@ -165,7 +168,11 @@ public function details(Order $order): Response if (!$order) { throw $this->createNotFoundException('Nie znaleziono zlecenia'); } - $logs = $this->entityManager->getRepository(Log::class)->findBy(['order' => $order], ['createdAt' => 'DESC'], 100); + $logs = $this->entityManager->getRepository(Log::class)->findBy( + ['order' => $order], + ['createdAt' => 'DESC'], + 100 + ); return $this->render('index/details.twig', [ 'order' => $order, @@ -175,8 +182,9 @@ public function details(Order $order): Response /** * @Route("/index/api/updateState/{id}/{state}", name="index_updateState") - * + * @param Order $order * @param $state + * @return Response */ public function updateState(Order $order, $state): Response { @@ -197,7 +205,8 @@ public function updateState(Order $order, $state): Response } $this->entityManager->persist(new Log( $this->getUser(), - 'Zmiana statusu: '.$currentState.' -> '.$state.'.', $order + 'Zmiana statusu: ' . $currentState . ' -> ' . $state . '.', + $order )); $this->entityManager->persist($order); $this->entityManager->flush(); diff --git a/src/Controller/InvoicesController.php b/src/Controller/InvoicesController.php index 9308884..4d6ad40 100644 --- a/src/Controller/InvoicesController.php +++ b/src/Controller/InvoicesController.php @@ -9,13 +9,12 @@ use App\Entity\Order; use App\Form\InvoiceMonthFormType; use App\Form\InvoiceSummaryForm; -use function curl_exec; +use Symfony\Component\HttpFoundation\Request; use DateTime; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\NoResultException; use Exception; -use function json_encode; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; @@ -23,13 +22,12 @@ class InvoicesController extends AbstractController { - private $entityManager; - private $request; - private $company; + private ?Request $request; - public function __construct(EntityManagerInterface $entityManager, RequestStack $requestStack) - { - $this->entityManager = $entityManager; + public function __construct( + private EntityManagerInterface $entityManager, + RequestStack $requestStack + ) { $this->request = $requestStack->getCurrentRequest(); } @@ -186,7 +184,7 @@ public function executeInvoice(): Response $this->request->get('client') ); - $url = 'https://'.$fakturowniaFirm.'.fakturownia.pl/invoices.json'; + $url = 'https://' . $fakturowniaFirm . '.fakturownia.pl/invoices.json'; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); @@ -198,18 +196,22 @@ public function executeInvoice(): Response if (!isset($result['id'])) { $text = 'Bład serwisu Fakturownia.pl'; if (isset($result['message'])) { - $text .= ': '.json_encode($result['message'], JSON_UNESCAPED_UNICODE); + $text .= ': ' . json_encode($result['message'], JSON_UNESCAPED_UNICODE); } - return new Response("
".$text.'
', 500); + return new Response("
" . $text . '
', 500); } $this->settle($orders); $this->logInvoice($orders); return new Response( - "
Wystawiono fakturę i ustawiono zlecenia na rozliczone.
Podgląd
", - 200); + "
" . + "Wystawiono fakturę i ustawiono zlecenia na rozliczone.
" . + "Podgląd
", + 200 + ); } private function getPayload($orders, $clientId): string @@ -217,8 +219,7 @@ private function getPayload($orders, $clientId): string $company = $this->entityManager->getRepository(Company::class)->findAll()[0]; $client = $this->entityManager ->getRepository(Client::class) - ->findOneBy(['id' => $clientId] - ); + ->findOneBy(['id' => $clientId]); $positions = []; foreach ($orders as $order) { @@ -314,7 +315,7 @@ public function reloadClients(): Response $month = $form->getData()['month']; $year = $form->getData()['year']; try { - $date = new DateTime($year.'-'.$month.'-01'); + $date = new DateTime($year . '-' . $month . '-01'); } catch (Exception $e) { $date = null; } @@ -329,7 +330,7 @@ public function reloadClients(): Response ]); } - return new Response('Błedne dane.', 406); + return new Response('Błędne dane.', 406); } private function logInvoice(Array $orders): void diff --git a/src/Controller/ReportsController.php b/src/Controller/ReportsController.php index 9998df7..8689a26 100644 --- a/src/Controller/ReportsController.php +++ b/src/Controller/ReportsController.php @@ -1,131 +1,131 @@ -render( - 'reports/index.html.twig', - ['reports' => ReportsFactory::REPORTS] - ); - } - - /** - * @Route("/reports/api/form/{report}", name="reports_form_report") - */ - public function getForm($report): JsonResponse - { - $service = $this->factory->getReportService($report); - return new JsonResponse([ - 'success' => true, - 'form' => $service->renderForm() - ]); - } - - /** - * @Route("/reports/api/details/{report}", name="reports_form_details") - */ - public function getDetails($report): JsonResponse - { - foreach (ReportsFactory::REPORTS as $rep) { - if ($rep['id'] == $report) { - return new JsonResponse([ - 'success' => true, - 'details' => $rep['details'] - ]); - } - } - return new JsonResponse(['success' => false, 'error' => 'Report not found.']); - } - - /** - * @param Request $request - * @param $report - * @return JsonResponse - * @throws Exception - * @Route("/reports/api/preview/{report}", name="reports_preview_report") - */ - public function getPreview(Request $request, $report): JsonResponse - { - $service = $this->factory->getReportService($report); - - if (!$service) { - return new JsonResponse(['success' => false, 'error' => 'Report type not found.']); - } - - $service->configure($request); - - $preview = $service->getPreview(); - - return new JsonResponse([ - 'success' => true, - 'preview' => $this->twig->render('reports/preview.html.twig', ['preview' => $preview]) - ]); - } - - /** - * @param Request $request - * @param $report - * @return JsonResponse - * @throws Exception - * @Route("/reports/api/export/{report}", name="reports_export_report") - */ - public function export(Request $request, $report): JsonResponse - { - $service = $this->factory->getReportService($report); - - if (!$service) { - return new JsonResponse(['success' => false, 'error' => 'Report type not found.']); - } - - $service->configure($request); - - $result = $service->export(); - - return new JsonResponse(['success' => true, 'path' => $result]); - } - - /** - * @param $report - * @return Response - * @Route("/reports/api/get/{report}", name="reports_get_report") - */ - public function getReport($report) : Response - { - if (file_exists('../var/tmp/' . $report)) { - $response = new BinaryFileResponse( - '../var/tmp/' . $report, - 200, - ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'] - ); - $response->setContentDisposition( - ResponseHeaderBag::DISPOSITION_ATTACHMENT, - 'certifed_ua_pl.xlsx' - ); - return $response; - } - return new JsonResponse(['success' => false, 'error' => 'File "' . $report . '" not found.']); - } -} \ No newline at end of file +render( + 'reports/index.html.twig', + ['reports' => ReportsFactory::REPORTS] + ); + } + + /** + * @Route("/reports/api/form/{report}", name="reports_form_report") + */ + public function getForm($report): JsonResponse + { + $service = $this->factory->getReportService($report); + return new JsonResponse([ + 'success' => true, + 'form' => $service->renderForm() + ]); + } + + /** + * @Route("/reports/api/details/{report}", name="reports_form_details") + */ + public function getDetails($report): JsonResponse + { + foreach (ReportsFactory::REPORTS as $rep) { + if ($rep['id'] == $report) { + return new JsonResponse([ + 'success' => true, + 'details' => $rep['details'] + ]); + } + } + return new JsonResponse(['success' => false, 'error' => 'Report not found.']); + } + + /** + * @param Request $request + * @param $report + * @return JsonResponse + * @throws Exception + * @Route("/reports/api/preview/{report}", name="reports_preview_report") + */ + public function getPreview(Request $request, $report): JsonResponse + { + $service = $this->factory->getReportService($report); + + if (!$service) { + return new JsonResponse(['success' => false, 'error' => 'Report type not found.']); + } + + $service->configure($request); + + $preview = $service->getPreview(); + + return new JsonResponse([ + 'success' => true, + 'preview' => $this->twig->render('reports/preview.html.twig', ['preview' => $preview]) + ]); + } + + /** + * @param Request $request + * @param $report + * @return JsonResponse + * @throws Exception + * @Route("/reports/api/export/{report}", name="reports_export_report") + */ + public function export(Request $request, $report): JsonResponse + { + $service = $this->factory->getReportService($report); + + if (!$service) { + return new JsonResponse(['success' => false, 'error' => 'Report type not found.']); + } + + $service->configure($request); + + $result = $service->export(); + + return new JsonResponse(['success' => true, 'path' => $result]); + } + + /** + * @param $report + * @return Response + * @Route("/reports/api/get/{report}", name="reports_get_report") + */ + public function getReport($report) : Response + { + if (file_exists('../var/tmp/' . $report)) { + $response = new BinaryFileResponse( + '../var/tmp/' . $report, + 200, + ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'] + ); + $response->setContentDisposition( + ResponseHeaderBag::DISPOSITION_ATTACHMENT, + 'certifed_ua_pl.xlsx' + ); + return $response; + } + return new JsonResponse(['success' => false, 'error' => 'File "' . $report . '" not found.']); + } +} diff --git a/src/Controller/TaskController.php b/src/Controller/TaskController.php index 424d8df..cc3a203 100644 --- a/src/Controller/TaskController.php +++ b/src/Controller/TaskController.php @@ -121,7 +121,11 @@ public function delete(Task $task): Response */ public function details(Task $task): Response { - $logs = $this->entityManager->getRepository(Log::class)->findBy(['task' => $task], ['createdAt' => 'DESC'], 100); + $logs = $this->entityManager->getRepository(Log::class)->findBy( + ['task' => $task], + ['createdAt' => 'DESC'], + 100 + ); return $this->render('tasks/details.twig', [ 'task' => $task, diff --git a/src/Entity/Order.php b/src/Entity/Order.php index dc0ecfd..0fd1a5f 100644 --- a/src/Entity/Order.php +++ b/src/Entity/Order.php @@ -151,7 +151,8 @@ public function getWarnings(): array if ($timeToDeadline < 0) { $warnings[] = 'Minął termin zlecenia, a jego status jest ustawiony na przyjęte'; } elseif ($timeToDeadline < 86400) { - $warnings[] = 'Pozostało mniej niż 24h do terminu zlecenia, a jego status jest ustawiony na przyjęte'; + $warnings[] = + 'Pozostało mniej niż 24h do terminu zlecenia, a jego status jest ustawiony na przyjęte'; } break; case self::WYKONANE: diff --git a/src/Entity/Staff.php b/src/Entity/Staff.php index 0ca1204..bdf0cd7 100644 --- a/src/Entity/Staff.php +++ b/src/Entity/Staff.php @@ -52,7 +52,7 @@ public function getId(): ?int public function __toString(): string { - return $this->getFirstName().' '.$this->getLastName(); + return $this->getFirstName() . ' ' . $this->getLastName(); } public function getFirstName(): ?string diff --git a/src/Entity/User.php b/src/Entity/User.php index 69b5cdc..2c94a94 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -190,7 +190,7 @@ public function setStaff(?Staff $staff): self public function __toString(): string { - return $this->getFirstName().' '.$this->getLastName(); + return $this->getFirstName() . ' ' . $this->getLastName(); } public function getFirstName(): ?string diff --git a/src/Form/AddOrderForm.php b/src/Form/AddOrderForm.php index fe5b366..70f0b30 100644 --- a/src/Form/AddOrderForm.php +++ b/src/Form/AddOrderForm.php @@ -20,11 +20,9 @@ class AddOrderForm extends AbstractType { - private $entityManager; - - public function __construct(EntityManagerInterface $entityManager) - { - $this->entityManager = $entityManager; + public function __construct( + private EntityManagerInterface $entityManager + ) { } public function buildForm(FormBuilderInterface $builder, array $options) @@ -52,7 +50,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'help' => 'Osoba relizująca zlecenie', 'label' => 'Tłumacz', 'choice_label' => function ($staff) { - return $staff->getFirstName().' '.$staff->getLastName(); + return $staff->getFirstName() . ' ' . $staff->getLastName(); }, ]) ->add('topic', TextType::class, [ diff --git a/src/Form/AddTaskForm.php b/src/Form/AddTaskForm.php index e1b63b5..32856e6 100644 --- a/src/Form/AddTaskForm.php +++ b/src/Form/AddTaskForm.php @@ -44,7 +44,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'label' => 'Wykonawca', 'class' => User::class, 'choice_label' => function ($user) { - return $user->getFirstName().' '.$user->getLastName(); + return $user->getFirstName() . ' ' . $user->getLastName(); }, 'query_builder' => function () { return $this->entityManager->getRepository(User::class)->createQueryBuilder('u') diff --git a/src/Form/InvoiceMonthFormType.php b/src/Form/InvoiceMonthFormType.php index 2f870b8..ab0d319 100644 --- a/src/Form/InvoiceMonthFormType.php +++ b/src/Form/InvoiceMonthFormType.php @@ -36,7 +36,7 @@ public function __construct(private EntityManagerInterface $entityManager) $f = intval($first->getDeadline()->format('Y')); $l = intval($last->getDeadline()->format('Y')); for ($i = $f; $i <= $l; ++$i) { - $this->years[$i.''] = $i; + $this->years[(string) $i] = $i; } } } catch (Exception $ex) { diff --git a/src/Kernel.php b/src/Kernel.php index d348267..ac0f4e0 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -15,24 +15,24 @@ class Kernel extends BaseKernel protected function configureContainer(ContainerConfigurator $container): void { $container->import('../config/{packages}/*.yaml'); - $container->import('../config/{packages}/'.$this->environment.'/*.yaml'); + $container->import('../config/{packages}/' . $this->environment . '/*.yaml'); - if (is_file(dirname(__DIR__).'/config/services.yaml')) { + if (is_file(dirname(__DIR__) . '/config/services.yaml')) { $container->import('../config/services.yaml'); - $container->import('../config/{services}_'.$this->environment.'.yaml'); - } elseif (is_file($path = dirname(__DIR__).'/config/services.php')) { + $container->import('../config/{services}_' . $this->environment . '.yaml'); + } elseif (is_file($path = dirname(__DIR__) . '/config/services.php')) { (require $path)($container->withPath($path), $this); } } protected function configureRoutes(RoutingConfigurator $routes): void { - $routes->import('../config/{routes}/'.$this->environment.'/*.yaml'); + $routes->import('../config/{routes}/' . $this->environment . '/*.yaml'); $routes->import('../config/{routes}/*.yaml'); - if (is_file(dirname(__DIR__).'/config/routes.yaml')) { + if (is_file(dirname(__DIR__) . '/config/routes.yaml')) { $routes->import('../config/routes.yaml'); - } elseif (is_file($path = dirname(__DIR__).'/config/routes.php')) { + } elseif (is_file($path = dirname(__DIR__) . '/config/routes.php')) { (require $path)($routes->withPath($path), $this); } } diff --git a/src/Security/LoginFormAuthenticator.php b/src/Security/LoginFormAuthenticator.php index 1bffc6b..fcc9e51 100644 --- a/src/Security/LoginFormAuthenticator.php +++ b/src/Security/LoginFormAuthenticator.php @@ -27,17 +27,12 @@ class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements P public const LOGIN_ROUTE = 'login'; - private $entityManager; - private $urlGenerator; - private $csrfTokenManager; - private $passwordEncoder; - - public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder) - { - $this->entityManager = $entityManager; - $this->urlGenerator = $urlGenerator; - $this->csrfTokenManager = $csrfTokenManager; - $this->passwordEncoder = $passwordEncoder; + public function __construct( + private EntityManagerInterface $entityManager, + private UrlGeneratorInterface $urlGenerator, + private CsrfTokenManagerInterface $csrfTokenManager, + private UserPasswordEncoderInterface $passwordEncoder + ) { } public function supports(Request $request): bool @@ -100,14 +95,18 @@ public function checkCredentials($credentials, UserInterface $user): bool * Used to upgrade (rehash) the user's password automatically over time. * * @param $credentials + * @return string|null */ public function getPassword($credentials): ?string { return $credentials['password']; } - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): RedirectResponse - { + public function onAuthenticationSuccess( + Request $request, + TokenInterface $token, + string $providerKey + ): RedirectResponse { if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } diff --git a/src/Service/ReportInterface.php b/src/Service/ReportInterface.php index 6e9167c..780624a 100644 --- a/src/Service/ReportInterface.php +++ b/src/Service/ReportInterface.php @@ -1,32 +1,32 @@ -twig->render('reports/forms/CERTIFIED_UA_PL.html.twig'); - } - - /** - * @throws Exception - */ - public function configure(Request $request): void - { - $from = $request->get('from'); - if ($from) { - $this->config['from'] = new \DateTime($from); - } - - $to = $request->get('to'); - if ($to) { - $this->config['to'] = new \DateTime($to); - } - } - - /** - * @return array - * @throws Exception - */ - public function getPreview(): array - { - if (!isset($this->config)) { - throw new Exception('Report not configured.'); - } - return $this->getArray(); - } - - - /** - * @return string - * @throws Exception - */ - public function export(): string - { - if (!isset($this->config)) { - throw new Exception('Report not configured.'); - } - - $array = $this->getArray(); - - $filename = uniqid() . '.xlsx'; - $path = '../var/tmp/' . $filename; - if (!file_exists('../var/tmp')) { - mkdir('../var/tmp', 775); - } - \SimpleXLSXGen::fromArray($array)->saveAs($path); - return $filename; - } - - private function getOrders() - { - $ua = $this->langRepository->findOneBy(['short' => 'UA']); - $pl = $this->langRepository->findOneBy(['short' => 'PL']); - - $queryBuilder = $this->orderRepository->createQueryBuilder('o'); - $queryBuilder = $queryBuilder - ->andWhere('o.deletedAt is null') - ->andWhere('o.certified = 1') - ->andWhere( - $queryBuilder->expr()->orX( - $queryBuilder->expr()->andX( - $queryBuilder->expr()->eq('o.baseLang', ':pl'), - $queryBuilder->expr()->eq('o.targetLang', ':ua') - ), - $queryBuilder->expr()->andX( - $queryBuilder->expr()->eq('o.baseLang', ':ua'), - $queryBuilder->expr()->eq('o.targetLang', ':pl') - ) - ) - ) - ->setParameter('ua', $ua) - ->setParameter('pl', $pl) - ->setMaxResults(1000); - - if (isset($this->config['from']) && $this->config['from']) { - $queryBuilder = $queryBuilder - ->andWhere('o.deadline > :from') - ->setParameter('from', $this->config['from']); - } - - if (isset($this->config['to']) && $this->config['to']) { - $queryBuilder = $queryBuilder - ->andWhere('o.deadline < :to') - ->setParameter('to', $this->config['to']); - } - - return $queryBuilder->getQuery()->getResult(); - } - - private function getArray() : array - { - $orders = $this->getOrders(); - - $table = []; - $sumOfNetto = 0; - - /** @var Order $order */ - foreach ($orders as $order) { - $table[] = [ - $order->getId(), - $order->getDeadline()->format('d.m.Y h:i'), - (string)$order->getClient(), - $order->getTopic(), - (string)$order->getStaff(), - (string)$order->getBaseLang(), - (string)$order->getTargetLang(), - $order->getCertified() ? 'tak' : 'nie', - $order->getPages(), - $order->getPrice(), - $order->getNetto(), - (string)$order->getState() - ]; - $sumOfNetto += $order->getNetto(); - } - $header = []; - $header[] = array_merge(array_fill(0, 10, ''), [$sumOfNetto, '']); - $header[] = [ - 'Id', - 'Termin', - 'Klient', - 'Temat', - 'Wykonawca', - 'Z', - 'Na', - 'UW', - 'L_str', - 'Cena', - 'Netto', - 'Status' - ]; - - return array_merge($header,$table); - } -} \ No newline at end of file +twig->render('reports/forms/CERTIFIED_UA_PL.html.twig'); + } + + /** + * @throws Exception + */ + public function configure(Request $request): void + { + $from = $request->get('from'); + if ($from) { + $this->config['from'] = new \DateTime($from); + } + + $to = $request->get('to'); + if ($to) { + $this->config['to'] = new \DateTime($to); + } + } + + /** + * @return array + * @throws Exception + */ + public function getPreview(): array + { + if (!isset($this->config)) { + throw new Exception('Report not configured.'); + } + return $this->getArray(); + } + + + /** + * @return string + * @throws Exception + */ + public function export(): string + { + if (!isset($this->config)) { + throw new Exception('Report not configured.'); + } + + $array = $this->getArray(); + + $filename = uniqid() . '.xlsx'; + $path = '../var/tmp/' . $filename; + if (!file_exists('../var/tmp')) { + mkdir('../var/tmp', 775); + } + \SimpleXLSXGen::fromArray($array)->saveAs($path); + return $filename; + } + + private function getOrders() + { + $ua = $this->langRepository->findOneBy(['short' => 'UA']); + $pl = $this->langRepository->findOneBy(['short' => 'PL']); + + $queryBuilder = $this->orderRepository->createQueryBuilder('o'); + $queryBuilder = $queryBuilder + ->andWhere('o.deletedAt is null') + ->andWhere('o.certified = 1') + ->andWhere( + $queryBuilder->expr()->orX( + $queryBuilder->expr()->andX( + $queryBuilder->expr()->eq('o.baseLang', ':pl'), + $queryBuilder->expr()->eq('o.targetLang', ':ua') + ), + $queryBuilder->expr()->andX( + $queryBuilder->expr()->eq('o.baseLang', ':ua'), + $queryBuilder->expr()->eq('o.targetLang', ':pl') + ) + ) + ) + ->setParameter('ua', $ua) + ->setParameter('pl', $pl) + ->setMaxResults(1000); + + if (isset($this->config['from']) && $this->config['from']) { + $queryBuilder = $queryBuilder + ->andWhere('o.deadline > :from') + ->setParameter('from', $this->config['from']); + } + + if (isset($this->config['to']) && $this->config['to']) { + $queryBuilder = $queryBuilder + ->andWhere('o.deadline < :to') + ->setParameter('to', $this->config['to']); + } + + return $queryBuilder->getQuery()->getResult(); + } + + private function getArray() : array + { + $orders = $this->getOrders(); + + $table = []; + $sumOfNetto = 0; + + /** @var Order $order */ + foreach ($orders as $order) { + $table[] = [ + $order->getId(), + $order->getDeadline()->format('d.m.Y h:i'), + (string)$order->getClient(), + $order->getTopic(), + (string)$order->getStaff(), + (string)$order->getBaseLang(), + (string)$order->getTargetLang(), + $order->getCertified() ? 'tak' : 'nie', + $order->getPages(), + $order->getPrice(), + $order->getNetto(), + (string)$order->getState() + ]; + $sumOfNetto += $order->getNetto(); + } + $header = []; + $header[] = array_merge(array_fill(0, 10, ''), [$sumOfNetto, '']); + $header[] = [ + 'Id', + 'Termin', + 'Klient', + 'Temat', + 'Wykonawca', + 'Z', + 'Na', + 'UW', + 'L_str', + 'Cena', + 'Netto', + 'Status' + ]; + + return array_merge($header, $table); + } +} diff --git a/src/Service/ReportsFactory.php b/src/Service/ReportsFactory.php index 18bb2bf..c2f42d5 100644 --- a/src/Service/ReportsFactory.php +++ b/src/Service/ReportsFactory.php @@ -1,35 +1,38 @@ - 'CERTIFIED_UA_PL', - 'name' => 'Albert', - 'details' => 'Tłumaczenia przysięgłe pl->ua i ua->pl', - ] - ]; - - public function __construct( - private OrderRepository $orderRepository, - private LangRepository $langRepository, - private Twig\Environment $twig - ){ - } - - #[Pure] public function getReportService(string $report) : ?ReportInterface - { - return match ($report) { - self::REPORTS[0]['id'] => new CertifiedUaPlReport($this->langRepository, $this->orderRepository, $this->twig), - default => null - }; - } -} \ No newline at end of file + 'CERTIFIED_UA_PL', + 'name' => 'Albert', + 'details' => 'Tłumaczenia przysięgłe pl->ua i ua->pl', + ] + ]; + + public function __construct( + private OrderRepository $orderRepository, + private LangRepository $langRepository, + private Twig\Environment $twig + ) { + } + + public function getReportService(string $report) : ?ReportInterface + { + return match ($report) { + self::REPORTS[0]['id'] => new CertifiedUaPlReport( + $this->langRepository, + $this->orderRepository, + $this->twig + ), + default => null + }; + } +} diff --git a/symfony.lock b/symfony.lock index 11ff5b2..e429592 100644 --- a/symfony.lock +++ b/symfony.lock @@ -148,6 +148,18 @@ "shuchkin/simplexlsxgen": { "version": "1.0.21" }, + "squizlabs/php_codesniffer": { + "version": "3.6", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "3.6", + "ref": "1019e5c08d4821cb9b77f4891f8e9c31ff20ac6f" + }, + "files": [ + "phpcs.xml.dist" + ] + }, "symfony/asset": { "version": "v5.2.1" },