diff --git a/dev_db/mariadb.sql b/dev_db/mariadb.sql index c1f85228c..6e7638342 100644 --- a/dev_db/mariadb.sql +++ b/dev_db/mariadb.sql @@ -2114,7 +2114,7 @@ CREATE TABLE `shop` ( `smtphostname` varchar(255) DEFAULT NULL, `smtpusername` varchar(255) DEFAULT NULL, `smtppassword` varchar(255) DEFAULT NULL, - `smtpusethis` int(1) NOT NULL, + `smtpusethis` int(1) NULL DEFAULT 0, `useemailaslogin` int(1) NOT NULL, `noverify` int(1) NOT NULL, `keywords` longtext DEFAULT NULL, diff --git a/src/new/config/packages/prod/doctrine.php b/src/new/config/packages/prod/doctrine.php index 692d26fcf..5fc9c5a75 100755 --- a/src/new/config/packages/prod/doctrine.php +++ b/src/new/config/packages/prod/doctrine.php @@ -5,7 +5,14 @@ declare(strict_types=1); use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return static function (ContainerConfigurator $containerConfigurator): void { - $containerConfigurator->extension('doctrine', ['orm' => ['auto_generate_proxy_classes' => false, 'metadata_cache_driver' => ['type' => 'pool', 'pool' => 'doctrine.system_cache_pool'], 'query_cache_driver' => ['type' => 'pool', 'pool' => 'doctrine.system_cache_pool'], 'result_cache_driver' => ['type' => 'pool', 'pool' => 'doctrine.result_cache_pool']]]); + $containerConfigurator->extension('doctrine', ['orm' => [ + 'metadata_cache_driver' => ['type' => 'pool', 'pool' => 'doctrine.system_cache_pool'], + 'query_cache_driver' => ['type' => 'pool', 'pool' => 'doctrine.system_cache_pool'], + 'result_cache_driver' => ['type' => 'pool', 'pool' => 'doctrine.result_cache_pool'], + ]]); - $containerConfigurator->extension('framework', ['cache' => ['pools' => ['doctrine.result_cache_pool' => ['adapter' => 'cache.app'], 'doctrine.system_cache_pool' => ['adapter' => 'cache.system']]]]); + $containerConfigurator->extension('framework', ['cache' => ['pools' => [ + 'doctrine.result_cache_pool' => ['adapter' => 'cache.app'], + 'doctrine.system_cache_pool' => ['adapter' => 'cache.system'], + ]]]); }; diff --git a/src/new/config/reference.php b/src/new/config/reference.php index 1875f986e..ff03dd202 100644 --- a/src/new/config/reference.php +++ b/src/new/config/reference.php @@ -2457,7 +2457,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; * length?: scalar|null, // Default: 5 * width?: scalar|null, // Default: 130 * height?: scalar|null, // Default: 50 - * font?: scalar|null, // Default: "/data/www/new/vendor/gregwar/captcha-bundle/DependencyInjection/../Generator/Font/captcha.ttf" + * font?: scalar|null, // Default: "/application/src/new/vendor/gregwar/captcha-bundle/DependencyInjection/../Generator/Font/captcha.ttf" * keep_value?: scalar|null, // Default: false * charset?: scalar|null, // Default: "abcdefhjkmnprstuvwxyz23456789" * as_file?: scalar|null, // Default: false diff --git a/src/new/fixtures/voucher.yml b/src/new/fixtures/voucher.yml index f5bbfb03a..0e3e1dd81 100644 --- a/src/new/fixtures/voucher.yml +++ b/src/new/fixtures/voucher.yml @@ -9,7 +9,7 @@ PSC\Shop\EntityBundle\Entity\Voucher: code: 5f mode: 1 fromDate: <(new DateTime("2023-12-12"))> - toDate: <(new DateTime("2025-12-12"))> + toDate: <(new DateTime("2026-12-12"))> value: 5 shop: '@shop_1' voucher_2: @@ -22,7 +22,7 @@ PSC\Shop\EntityBundle\Entity\Voucher: code: 5p mode: 1 fromDate: <(new DateTime("2023-12-12"))> - toDate: <(new DateTime("2025-12-12"))> + toDate: <(new DateTime("2026-12-12"))> value: 5 shop: '@shop_1' voucher_3: @@ -37,7 +37,7 @@ PSC\Shop\EntityBundle\Entity\Voucher: zeroShipping: false mode: 1 fromDate: <(new DateTime("2023-12-12"))> - toDate: <(new DateTime("2025-12-12"))> + toDate: <(new DateTime("2026-12-12"))> value: 0 shop: '@shop_1' voucher_4: @@ -52,7 +52,7 @@ PSC\Shop\EntityBundle\Entity\Voucher: zeroShipping: true mode: 1 fromDate: <(new DateTime("2023-12-12"))> - toDate: <(new DateTime("2025-12-12"))> + toDate: <(new DateTime("2026-12-12"))> value: 0 shop: '@shop_1' diff --git a/src/new/sqlshop_instancen b/src/new/sqlshop_instancen index be60ceffc..42e0f8d05 100755 --- a/src/new/sqlshop_instancen +++ b/src/new/sqlshop_instancen @@ -1780,7 +1780,7 @@ CREATE TABLE `shop` ( `smtphostname` varchar(255) NOT NULL, `smtpusername` varchar(255) NOT NULL, `smtppassword` varchar(255) NOT NULL, - `smtpusethis` int(1) NOT NULL, + `smtpusethis` int(1) NULL DEFAULT 0, `useemailaslogin` int(1) NOT NULL, `noverify` int(1) NOT NULL, `keywords` longtext, diff --git a/src/new/src/PSC/Backend/DashboardBundle/Controller/ShopController.php b/src/new/src/PSC/Backend/DashboardBundle/Controller/ShopController.php index ad0a0c1e2..c39a26276 100755 --- a/src/new/src/PSC/Backend/DashboardBundle/Controller/ShopController.php +++ b/src/new/src/PSC/Backend/DashboardBundle/Controller/ShopController.php @@ -19,17 +19,11 @@ use PSC\Shop\EntityBundle\Entity\Domain; use PSC\System\SettingsBundle\Service\Shop; use Symfony\Bridge\Twig\Attribute\Template; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; -/** - * ShopController fürs ProductionBundle - * - * @package PSC\Backend\Production - * @subpackage Controller - */ class ShopController extends AbstractController { #[IsGranted('ROLE_SHOP')] @@ -88,24 +82,10 @@ class ShopController extends AbstractController ]; } - /** - * Change Shop - * - * - * @param Request $request - * @param EntityManagerInterface $em - * @param \Symfony\Component\Security\Core\Security $security - * @param $shop_uuid - * @return RedirectResponse - */ #[IsGranted('ROLE_SHOP')] #[Route(path: '/shop/change/{shop_uuid}', name: 'psc_backend_dashboard_shop_change')] - public function changeShopAction( - Request $request, - EntityManagerInterface $em, - \Symfony\Component\Security\Core\Security $security, - $shop_uuid, - ) { + public function changeShopAction(Request $request, EntityManagerInterface $em, Security $security, $shop_uuid) + { $em->getRepository('PSC\Shop\EntityBundle\Entity\ShopContact')->changeSelectedShop( $security->getUser(), $shop_uuid, @@ -114,23 +94,12 @@ class ShopController extends AbstractController return $this->redirect($this->generateUrl('psc_backend_dashboard_index')); } - /** - * Change Shop - * - * - * @param Request $request - * @param EntityManagerInterface $em - * @param \Symfony\Component\Security\Core\Security $security - * @param Shop $shopService - * @return RedirectResponse - * @throws \Doctrine\ORM\ORMException - */ #[IsGranted('ROLE_SHOP')] #[Route(path: '/shop/deleted/toogle', name: 'psc_backend_dashboard_toogle_deleted_shop')] public function toogleDisplayDeletedShopAction( Request $request, EntityManagerInterface $em, - \Symfony\Component\Security\Core\Security $security, + Security $security, Shop $shopService, ) { /** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ diff --git a/src/new/src/PSC/Shop/OrderBundle/Normalizer/SpecialProductDenormalizer.php b/src/new/src/PSC/Shop/OrderBundle/Normalizer/SpecialProductDenormalizer.php index c4d0188b7..b98160d11 100755 --- a/src/new/src/PSC/Shop/OrderBundle/Normalizer/SpecialProductDenormalizer.php +++ b/src/new/src/PSC/Shop/OrderBundle/Normalizer/SpecialProductDenormalizer.php @@ -5,6 +5,7 @@ namespace PSC\Shop\OrderBundle\Normalizer; use BadMethodCallException; use PSC\Shop\OrderBundle\Model\Order\Position\IProductTypeObject; use PSC\System\PluginBundle\Service\ProductType; +use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; @@ -45,6 +46,6 @@ class SpecialProductDenormalizer implements DenormalizerInterface, DenormalizerA public function getSupportedTypes(null|string $format): array { - return [IProductTypeObject::class]; + return [IProductTypeObject::class => true]; } } diff --git a/src/new/src/PSC/Shop/OrderBundle/Resources/config/services.yml b/src/new/src/PSC/Shop/OrderBundle/Resources/config/services.yml index 8d78b83b9..257b05350 100755 --- a/src/new/src/PSC/Shop/OrderBundle/Resources/config/services.yml +++ b/src/new/src/PSC/Shop/OrderBundle/Resources/config/services.yml @@ -34,3 +34,7 @@ services: PSC\Shop\OrderBundle\Api\Position\GetPluginListDisplay: arguments: - !tagged_iterator order.backend.list.position + + PSC\Shop\OrderBundle\Normalizer\SpecialProductDenormalizer: + tags: + - { name: serializer.normalizer, priority: 1000 } diff --git a/src/new/src/PSC/Shop/VoucherBundle/Service/Voucher.php b/src/new/src/PSC/Shop/VoucherBundle/Service/Voucher.php index c9ad25398..2deee51ef 100644 --- a/src/new/src/PSC/Shop/VoucherBundle/Service/Voucher.php +++ b/src/new/src/PSC/Shop/VoucherBundle/Service/Voucher.php @@ -8,18 +8,18 @@ use PSC\Shop\VoucherBundle\Model\Voucher as PSCVoucher; class Voucher { - public function __construct(private VoucherRepository $voucherRepository) - { - } + public function __construct( + private VoucherRepository $voucherRepository, + ) {} - public function getVoucherForCode(string $code, Shop $shop): ?PSCVoucher + public function getVoucherForCode(string $code, Shop $shop): null|PSCVoucher { $voucherEntity = $this->voucherRepository->findByCodeForActDate($code, $shop); - if($voucherEntity) { + if ($voucherEntity) { $v = new PSCVoucher(); $v->setMore($voucherEntity->isMore()); $v->setCode($code); - if($voucherEntity->isPercent()) { + if ($voucherEntity->isPercent()) { $v->setPercentValue($voucherEntity->getValue()); } else { $v->setValueInCent($voucherEntity->getValue() * 100); diff --git a/src/new/src/PSC/System/SettingsBundle/Api/Papercontainer/Update.php b/src/new/src/PSC/System/SettingsBundle/Api/Papercontainer/Update.php index 265c9bbf6..406119e3c 100755 --- a/src/new/src/PSC/System/SettingsBundle/Api/Papercontainer/Update.php +++ b/src/new/src/PSC/System/SettingsBundle/Api/Papercontainer/Update.php @@ -11,9 +11,9 @@ use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use PSC\System\SettingsBundle\Model\Papercontainer; use PSC\System\SettingsBundle\Service\Shop; -use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; @@ -38,8 +38,8 @@ class Update extends AbstractController #[Security(name: 'Bearer')] #[Route(path: '/papercontainer', methods: ['PUT'])] #[RequestBody(content: new JsonContent(ref: new Model(type: Papercontainer::class)))] - #[IsGranted('ROLE_USER')] - public function updatePapercontainer(Papercontainer $papercontainer): JsonResponse + #[IsGranted('ROLE_USER')] + public function updatePapercontainer(#[MapRequestPayload] Papercontainer $papercontainer): JsonResponse { $install = $this->shopService->getShopByDomain()->getInstall(); $install->setPaperContainer($papercontainer->getContent()); diff --git a/src/new/tests/PSC/Shop/Contact/Api/AllTest.php b/src/new/tests/PSC/Shop/Contact/Api/AllTest.php index 6249b04d9..961326889 100755 --- a/src/new/tests/PSC/Shop/Contact/Api/AllTest.php +++ b/src/new/tests/PSC/Shop/Contact/Api/AllTest.php @@ -2,10 +2,10 @@ namespace Tests\PSC\Shop\Contact\Api; -use Tests\RefreshDatabaseTrait; use PSC\Shop\ContactBundle\Repository\ContactRepository; use PSC\Shop\EntityBundle\Repository\ShopRepository; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use Tests\RefreshDatabaseTrait; class AllTest extends WebTestCase { @@ -26,9 +26,8 @@ class AllTest extends WebTestCase $data = json_decode($client->getResponse()->getContent(), true); self::assertSame(3, count($data['data'])); - self::assertSame("test3@shop.de", $data['data'][0]['email']); - self::assertSame("test@shop.de", $data['data'][1]['email']); - self::assertSame("admin@shop.de", $data['data'][2]['email']); - + self::assertSame('test3@shop.de', $data['data'][1]['email']); + self::assertSame('test@shop.de', $data['data'][0]['email']); + self::assertSame('admin@shop.de', $data['data'][2]['email']); } } diff --git a/src/new/tests/PSC/Shop/Payment/Controller/ListTest.php b/src/new/tests/PSC/Shop/Payment/Controller/ListTest.php index a5c9b8e5b..e6a3098f9 100755 --- a/src/new/tests/PSC/Shop/Payment/Controller/ListTest.php +++ b/src/new/tests/PSC/Shop/Payment/Controller/ListTest.php @@ -1,10 +1,11 @@ request('GET', '/backend/payment/list/index'); $this->assertResponseIsSuccessful(); - $crawler = $crawler->filter('.table > tbody > tr'); + $crawler = $crawler->filter('table > tbody > tr'); $this->assertSame(4, $crawler->count()); } } diff --git a/src/new/tests/PSC/Shop/Payment/E2E/ListTest.php b/src/new/tests/PSC/Shop/Payment/E2E/ListTest.php index 0269a88af..2f2da7d1b 100644 --- a/src/new/tests/PSC/Shop/Payment/E2E/ListTest.php +++ b/src/new/tests/PSC/Shop/Payment/E2E/ListTest.php @@ -20,11 +20,7 @@ class ListTest extends PantherTestCase $chromeOptions->addArguments(['--window-size=1200,1100', '--disable-gpu']); $capabilities = DesiredCapabilities::chrome(); $capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); - $this->client = Client::createSeleniumClient( - 'http://chrome:4444', - $capabilities, - 'http://application:9001' - ); + $this->client = Client::createSeleniumClient('http://chrome:4444', $capabilities, 'http://application:9001'); static::startWebServer(['hostname' => 'application']); } @@ -32,7 +28,7 @@ class ListTest extends PantherTestCase { $this->client->close(); unset($this->client); - static::stopWebServer(); + static::stopWebServer(); } public function testPaymentList(): void @@ -40,9 +36,20 @@ class ListTest extends PantherTestCase $this->client->get('/backend/login'); $crawler = $this->client->submitForm('login', ['username' => 'admin@shop.de', 'password' => 'shop2014']); $crawler = $this->client->get('/backend/dashboard'); - self::assertSame('Dashboard', $this->client->getCrawler()->filter('h1')->text()); - $crawler = $this->client->clickLink('Zahlarten'); - self::assertStringContainsString('Zahlarten', $this->client->getCrawler()->filter('h3')->text()); + self::assertSame( + 'Dashboard', + $this->client + ->getCrawler() + ->filter('h1') + ->text(), + ); + $crawler = $this->client->clickLink('Zahlarten'); + self::assertStringContainsString( + 'Zahlarten', + $this->client + ->getCrawler() + ->filter('h1') + ->text(), + ); } - } diff --git a/src/new/tests/PSC/Shop/Shipping/Controller/ListTest.php b/src/new/tests/PSC/Shop/Shipping/Controller/ListTest.php index 219a1842d..f78f6045e 100755 --- a/src/new/tests/PSC/Shop/Shipping/Controller/ListTest.php +++ b/src/new/tests/PSC/Shop/Shipping/Controller/ListTest.php @@ -1,10 +1,11 @@ request('GET', '/backend/shipping/list/index'); $this->assertResponseIsSuccessful(); - $crawler = $crawler->filter('.table > tbody > tr'); + $crawler = $crawler->filter('table > tbody > tr'); $this->assertSame(4, $crawler->count()); } -} \ No newline at end of file +} + diff --git a/src/new/tests/mariadb.sql b/src/new/tests/mariadb.sql index 5c5f31d84..7116c5944 100644 --- a/src/new/tests/mariadb.sql +++ b/src/new/tests/mariadb.sql @@ -2114,7 +2114,7 @@ CREATE TABLE `shop` ( `smtphostname` varchar(255) DEFAULT NULL, `smtpusername` varchar(255) DEFAULT NULL, `smtppassword` varchar(255) DEFAULT NULL, - `smtpusethis` int(1) NOT NULL, + `smtpusethis` int(1) DEFAULT 0, `useemailaslogin` int(1) NOT NULL, `noverify` int(1) NOT NULL, `keywords` longtext DEFAULT NULL, diff --git a/src/new/tests/mysql.sql b/src/new/tests/mysql.sql index ff37969c1..797f1e72d 100644 --- a/src/new/tests/mysql.sql +++ b/src/new/tests/mysql.sql @@ -2110,7 +2110,7 @@ CREATE TABLE `shop` ( `smtphostname` varchar(255) DEFAULT NULL, `smtpusername` varchar(255) DEFAULT NULL, `smtppassword` varchar(255) DEFAULT NULL, - `smtpusethis` int(1) NOT NULL, + `smtpusethis` int(1) NULL DEFAULT 0, `useemailaslogin` int(1) NOT NULL, `noverify` int(1) NOT NULL, `keywords` longtext DEFAULT NULL, diff --git a/src/new/var/plugins/Custom/PSC/FormBuilder/Api/Layout/Add.php b/src/new/var/plugins/Custom/PSC/FormBuilder/Api/Layout/Add.php index b73fe56cc..6cb1c8b6a 100644 --- a/src/new/var/plugins/Custom/PSC/FormBuilder/Api/Layout/Add.php +++ b/src/new/var/plugins/Custom/PSC/FormBuilder/Api/Layout/Add.php @@ -5,15 +5,14 @@ namespace Plugin\Custom\PSC\FormBuilder\Api\Layout; use Doctrine\ODM\MongoDB\DocumentManager; use Nelmio\ApiDocBundle\Attribute\Model; use Nelmio\ApiDocBundle\Attribute\Security; -use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use Plugin\Custom\PSC\FormBuilder\Document\Layout as PSCLayout; use Plugin\Custom\PSC\FormBuilder\Dto\Layout\Input; use Plugin\Custom\PSC\FormBuilder\Model\Layout; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; @@ -27,10 +26,9 @@ class Add extends AbstractController #[Route(path: '/layouts/add', methods: ['POST'])] #[Tag('FormBuilder')] #[RequestBody(content: new Model(type: Input::class))] - #[ParamConverter('data', class: Input::class, converter: 'psc_rest.request_body')] #[IsGranted('ROLE_ADMIN')] #[Security(name: 'Security')] - public function add(Input $data) + public function add(#[MapRequestPayload] Input $data) { $layout = new PSCLayout(); $layout->setTitle($data->title); diff --git a/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Load.php b/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Load.php new file mode 100644 index 000000000..b430baf4d --- /dev/null +++ b/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Load.php @@ -0,0 +1,64 @@ +getRepository(Layoutdesigndata::class) + ->findOneBy(['uuid' => $layouterUUId]); + + if (!$layoutDesignData) { + return new JsonResponse(['error' => 'Layouter session not found'], JsonResponse::HTTP_NOT_FOUND); + } + + $design = $layoutDesignData->getDesign(); + $files = $design['files'] ?? []; + + // Enrich files with media URLs + $enrichedFiles = []; + foreach ($files as $fileData) { + $mediaUuid = $fileData['uuid'] ?? null; + if ($mediaUuid) { + /** @var Media|null $media */ + $media = $documentManager + ->getRepository(Media::class) + ->findOneBy(['_id' => new ObjectId($mediaUuid['$oid'])]); + + if ($media) { + $fileData['url'] = $media->getUrl(); + } + } + $enrichedFiles[] = $fileData; + } + + return new JsonResponse([ + 'success' => true, + 'layouterUUId' => $layoutDesignData->getUuid(), + 'productUUId' => $layoutDesignData->getArticleUuid(), + 'files' => $enrichedFiles, + ]); + } +} diff --git a/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Save.php b/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Save.php index 95027ae9c..6244f08f4 100644 --- a/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Save.php +++ b/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Api/Save.php @@ -19,17 +19,25 @@ class Save #[Tag(name: 'Plugin/Custom/PSC/LaufkartenLayouter')] public function saveAction(#[MapRequestPayload] Input $data, EntityManagerInterface $entityManager): JsonResponse { - $layoutDesignData = new Layoutdesigndata(); - $layoutDesignData->setUuid($data->layouterUUId); - $layoutDesignData->setArticleUuid($data->productUUId); - $layoutDesignData->setDesign(['files' => $data->files]); + // Check if layouter session already exists (edit mode) + $layoutDesignData = $entityManager + ->getRepository(Layoutdesigndata::class) + ->findOneBy(['uuid' => $data->layouterUUId]); + + if ($layoutDesignData) { + // Update existing session + $layoutDesignData->setDesign(['files' => $data->files]); + } else { + // Create new session + $layoutDesignData = new Layoutdesigndata(); + $layoutDesignData->setUuid($data->layouterUUId); + $layoutDesignData->setArticleUuid($data->productUUId); + $layoutDesignData->setDesign(['files' => $data->files]); + $entityManager->persist($layoutDesignData); + } - $entityManager->persist($layoutDesignData); $entityManager->flush(); - $json = new JsonResponse(); - $json->setContent(json_encode(['success' => true])); - - return $json; + return new JsonResponse(['success' => true]); } } diff --git a/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Resources/views/designer/start.html.twig b/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Resources/views/designer/start.html.twig index d42f41827..84b05d817 100644 --- a/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Resources/views/designer/start.html.twig +++ b/src/new/var/plugins/Custom/PSC/LaufkartenLayouter/Resources/views/designer/start.html.twig @@ -212,10 +212,96 @@ let pdfData = []; let thumbnails = {}; let ocrPreviews = {}; + const layouterUUId = '{{ layouterUUId }}'; + const isEditMode = layouterUUId && layouterUUId !== ''; // Initialize PDF.js pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js'; + // Load existing layouter session if in edit mode + async function loadLayouterSession() { + if (!isEditMode) { + return; + } + + try { + const response = await fetch(`/apps/api/plugin/custom/psc/laufkartenlayouter/load/${layouterUUId}`); + + if (!response.ok) { + throw new Error(`Failed to load layouter session: ${response.status}`); + } + + const data = await response.json(); + console.log('Loaded layouter session:', data); + + if (data.files && data.files.length > 0) { + // Convert loaded files to uploadedFiles format + // We need to fetch the actual PDF files from the media URLs + const loadingPromises = data.files.map(async (fileData) => { + try { + // Fetch the PDF file from the URL + const pdfResponse = await fetch(fileData.url || ''); + const pdfBlob = await pdfResponse.blob(); + const pdfFile = new File([pdfBlob], fileData.fileName, { type: 'application/pdf' }); + + return { + file: pdfFile, + uuid: fileData.uuid, + fileName: fileData.fileName, + ocrNumber: fileData.ocrNumber || '', + inRed: fileData.inRed || false, + numPages: fileData.numPages || 0, + isDuplex: fileData.isDuplex || false + }; + } catch (error) { + console.error(`Failed to load file ${fileData.fileName}:`, error); + return null; + } + }); + + const loadedFiles = (await Promise.all(loadingPromises)).filter(f => f !== null); + + if (loadedFiles.length > 0) { + // Populate uploadedFiles and enable next button + uploadedFiles = loadedFiles.map(f => f.file); + displayUploadedFiles(); + document.getElementById('nextToStep2').disabled = false; + + // Pre-populate pdfData with loaded metadata + pdfData = loadedFiles.map((fileData, index) => ({ + index: index, + file: fileData.file, + fileName: fileData.fileName, + numPages: fileData.numPages, + isDuplex: fileData.isDuplex, + ocrNumber: fileData.ocrNumber, + inRed: fileData.inRed, + processed: fileData.ocrNumber ? true : false, + uploadedUuid: fileData.uuid, + isAlreadyUploaded: true // Mark as already uploaded + })); + + // Initialize placeholder thumbnails for loaded files + pdfData.forEach((pdf, index) => { + thumbnails[index] = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjYwIiBoZWlnaHQ9IjgwIiBmaWxsPSIjZTVlN2ViIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtc2l6ZT0iMTQiIGZpbGw9IiM5Y2EzYWYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiPlBERjwvdGV4dD48L3N2Zz4='; + }); + + console.log(`Loaded ${loadedFiles.length} files from saved session`); + } + } + } catch (error) { + console.error('Error loading layouter session:', error); + alert('Fehler beim Laden der gespeicherten Session: ' + error.message); + } + } + + // Initialize on page load + document.addEventListener('DOMContentLoaded', () => { + if (isEditMode) { + loadLayouterSession(); + } + }); + // Save current form values function saveCurrentFormValues() { if (currentStep === 2 && pdfData.length > 0) { @@ -233,7 +319,7 @@ } // Step navigation - function goToStep(step) { + async function goToStep(step) { // Save current values before switching saveCurrentFormValues(); @@ -262,12 +348,29 @@ currentStep = step; if (step === 2) { + // Check if we have more uploadedFiles than pdfData (new files added) + const hasNewFiles = uploadedFiles.length > pdfData.length; + if (uploadedFiles.length > 0 && pdfData.length === 0) { - // First time going to step 2 - initializePDFData(); + // First time going to step 2 - initialize PDFs + await initializePDFData(); + } else if (hasNewFiles) { + // New files were added - initialize only the new ones + await initializeNewPDFData(); } else if (pdfData.length > 0) { - // Returning to step 2, refresh table with saved values - updatePDFTable(); + // Already have pdfData (from loading or previous visit) + // Check if we need to generate real thumbnails (not just placeholders) + const needsThumbnails = pdfData.some((pdf, index) => { + const thumb = thumbnails[index]; + return !thumb || thumb.includes('data:image/svg+xml'); + }); + + if (needsThumbnails) { + await generateThumbnailsForLoadedData(); + } else { + // Just refresh table with existing data + updatePDFTable(); + } } } if (step === 3) { @@ -275,6 +378,144 @@ } } + // Initialize only newly added PDF files (when files are added in edit mode) + async function initializeNewPDFData() { + const startIndex = pdfData.length; + const newFiles = uploadedFiles.slice(startIndex); + + if (newFiles.length === 0) { + return; + } + + const initialLoading = document.getElementById('initialLoading'); + const initialProgressBar = document.getElementById('initial-progress-bar'); + const initialProgressText = document.getElementById('initial-progress-text'); + const pdfTableContainer = document.getElementById('pdfTableContainer'); + const progressBar = document.getElementById('loading-progress-bar'); + const progressText = document.getElementById('loading-progress-text'); + const progressContainer = document.getElementById('loading-progress'); + + // Show loading + initialLoading.classList.remove('hidden'); + pdfTableContainer.classList.add('hidden'); + + // Phase 1: Quick metadata loading for new files + for (let i = 0; i < newFiles.length; i++) { + const file = newFiles[i]; + const fileReader = new FileReader(); + const globalIndex = startIndex + i; + + const progress1 = Math.round(((i + 1) / newFiles.length) * 100); + initialProgressBar.style.width = `${progress1}%`; + initialProgressText.textContent = `${i + 1} / ${newFiles.length}`; + + await new Promise((resolve) => { + fileReader.onload = async function() { + const typedArray = new Uint8Array(this.result); + const pdf = await pdfjsLib.getDocument(typedArray).promise; + const numPages = pdf.numPages; + + pdfData.push({ + index: globalIndex, + file: file, + fileName: file.name, + numPages: numPages, + isDuplex: numPages % 2 === 0 && numPages > 1, + ocrNumber: '', + inRed: false, + processed: false, + isAlreadyUploaded: false // Mark as NOT uploaded yet + }); + + thumbnails[globalIndex] = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjYwIiBoZWlnaHQ9IjgwIiBmaWxsPSIjZTVlN2ViIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtc2l6ZT0iMTQiIGZpbGw9IiM5Y2EzYWYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiPlBERjwvdGV4dD48L3N2Zz4='; + + resolve(); + }; + fileReader.readAsArrayBuffer(file); + }); + } + + // Hide initial loading, show table + initialLoading.classList.add('hidden'); + pdfTableContainer.classList.remove('hidden'); + updatePDFTable(); + + // Show Phase 2 progress + progressContainer.classList.remove('hidden'); + + // Phase 2: Generate thumbnails for ALL files (old placeholders + new files) + const filesToProcess = []; + + // Add old files that still have placeholders + for (let i = 0; i < startIndex; i++) { + const thumb = thumbnails[i]; + if (!thumb || thumb.includes('data:image/svg+xml')) { + filesToProcess.push(i); + } + } + + // Add all new files + for (let i = 0; i < newFiles.length; i++) { + filesToProcess.push(startIndex + i); + } + + // Generate thumbnails + for (let i = 0; i < filesToProcess.length; i++) { + const fileIndex = filesToProcess[i]; + const progress = Math.round(((i + 1) / filesToProcess.length) * 100); + progressBar.style.width = `${progress}%`; + progressText.textContent = `Lade Vorschau ${i + 1}/${filesToProcess.length}`; + + await generateThumbnail(fileIndex); + updatePDFTable(); + await new Promise(resolve => setTimeout(resolve, 10)); + } + + progressContainer.classList.add('hidden'); + } + + // Generate thumbnails for already loaded data (from session) + async function generateThumbnailsForLoadedData() { + const initialLoading = document.getElementById('initialLoading'); + const pdfTableContainer = document.getElementById('pdfTableContainer'); + const progressBar = document.getElementById('loading-progress-bar'); + const progressText = document.getElementById('loading-progress-text'); + const progressContainer = document.getElementById('loading-progress'); + + // Show loading + initialLoading.classList.remove('hidden'); + pdfTableContainer.classList.add('hidden'); + + // Initialize with placeholders + pdfData.forEach((pdf, index) => { + thumbnails[index] = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjYwIiBoZWlnaHQ9IjgwIiBmaWxsPSIjZTVlN2ViIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtc2l6ZT0iMTQiIGZpbGw9IiM5Y2EzYWYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiPlBERjwvdGV4dD48L3N2Zz4='; + }); + + // Show table immediately + initialLoading.classList.add('hidden'); + pdfTableContainer.classList.remove('hidden'); + updatePDFTable(); + + if (pdfData.length > 0) { + loadPDFInfo(0); + } + + // Generate thumbnails in background + progressContainer.classList.remove('hidden'); + + for (let i = 0; i < pdfData.length; i++) { + const progress = Math.round(((i + 1) / pdfData.length) * 100); + progressBar.style.width = `${progress}%`; + progressText.textContent = `Lade Vorschau ${i + 1}/${pdfData.length}`; + + await generateThumbnail(i); + updatePDFTable(); + await new Promise(resolve => setTimeout(resolve, 10)); + } + + progressContainer.classList.add('hidden'); + } + // Initialize PDF data and table async function initializePDFData() { pdfData = []; @@ -316,7 +557,8 @@ isDuplex: numPages % 2 === 0 && numPages > 1, ocrNumber: '', inRed: false, - processed: false + processed: false, + isAlreadyUploaded: false // New files need to be uploaded }); // Use placeholder thumbnail initially @@ -844,21 +1086,30 @@ const uploadedUUIDs = []; for (let i = 0; i < pdfData.length; i++) { - finishBtn.textContent = `Uploading PDFs... (${i + 1}/${pdfData.length})`; - const uploadResult = await uploadSinglePDF(pdfData[i], i); + let uploadUuid; + + // Check if this file was already uploaded (from loaded session or previous upload) + if (pdfData[i].isAlreadyUploaded && pdfData[i].uploadedUuid) { + console.log(`Skipping upload for ${pdfData[i].fileName} - already uploaded (UUID: ${pdfData[i].uploadedUuid})`); + uploadUuid = pdfData[i].uploadedUuid; + } else { + // Upload new file + finishBtn.textContent = `Uploading PDFs... (${i + 1}/${pdfData.length})`; + const uploadResult = await uploadSinglePDF(pdfData[i], i); + uploadUuid = uploadResult.uuid; + pdfData[i].uploadedUuid = uploadUuid; + pdfData[i].isAlreadyUploaded = true; // Mark as uploaded now + console.log(`Uploaded ${pdfData[i].fileName}: ${uploadUuid}`); + } - // Store UUID in pdfData - pdfData[i].uploadedUuid = uploadResult.uuid; uploadedUUIDs.push({ - uuid: uploadResult.uuid, + uuid: uploadUuid, fileName: pdfData[i].fileName, ocrNumber: pdfData[i].ocrNumber, inRed: pdfData[i].inRed, numPages: pdfData[i].numPages, isDuplex: pdfData[i].isDuplex }); - - console.log(`Uploaded ${pdfData[i].fileName}: ${uploadResult.uuid}`); } // Step 2: Call layouter/save with all UUIDs diff --git a/src/new/var/plugins/System/PSC/CaptchaFox/Api/Validate.php b/src/new/var/plugins/System/PSC/CaptchaFox/Api/Validate.php index 351a92dec..0cbc791f3 100755 --- a/src/new/var/plugins/System/PSC/CaptchaFox/Api/Validate.php +++ b/src/new/var/plugins/System/PSC/CaptchaFox/Api/Validate.php @@ -2,7 +2,6 @@ namespace Plugin\System\PSC\CaptchaFox\Api; - use Nelmio\ApiDocBundle\Annotation\Model; use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\RequestBody; @@ -10,30 +9,30 @@ use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use phpDocumentor\Reflection\Types\Boolean; use Plugin\System\PSC\FriendlyCaptcha\Dto\Input; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpClient\Exception\ClientException; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Contracts\HttpClient\HttpClientInterface; class Validate extends AbstractController { + public function __construct( + private readonly \PSC\System\SettingsBundle\Service\Shop $shopService, + private readonly HttpClientInterface $client, + ) {} - public function __construct(private readonly \PSC\System\SettingsBundle\Service\Shop $shopService, private readonly HttpClientInterface $client) - { - - } - - #[RequestBody(description: 'contact',content: new JsonContent(ref: new Model(type: Input::class)))] - #[Response(response: 200, description: 'validate token', content: new JsonContent(ref: new Model(type: Boolean::class)))] - #[ParamConverter('data', class: Input::class, converter: 'psc_rest.request_body')] - + #[RequestBody(description: 'contact', content: new JsonContent(ref: new Model(type: Input::class)))] + #[Response( + response: 200, + description: 'validate token', + content: new JsonContent(ref: new Model(type: Boolean::class)), + )] #[Tag('Plugin/System/PSC/CaptchaFox')] #[Route(path: '/validate', methods: ['POST'])] - public function validate(Input $data): JsonResponse + public function validate(#[MapRequestPayload] Input $data): JsonResponse { - $shop = $this->shopService->getMongoShopByUid($this->shopService->getShopByUid($data->shop_uuid)->getUID()); try { @@ -41,16 +40,15 @@ class Validate extends AbstractController 'body' => [ 'solution' => $data->token, 'sitekey' => $shop->getPluginSettingModule('captchafox', 'sitekey'), - 'secret' => $shop->getPluginSettingModule('captchafox', 'secret') + 'secret' => $shop->getPluginSettingModule('captchafox', 'secret'), ], ]); - }catch(ClientException $e) { - if($e->getCode() == 400) { + } catch (ClientException $e) { + if ($e->getCode() == 400) { return new JsonResponse(['success' => false]); } } return new JsonResponse(json_decode($response->getContent(), true)); - } } diff --git a/src/new/var/plugins/System/PSC/FriendlyCaptcha/Api/Validate.php b/src/new/var/plugins/System/PSC/FriendlyCaptcha/Api/Validate.php index 815cbd342..bf4a9fe01 100755 --- a/src/new/var/plugins/System/PSC/FriendlyCaptcha/Api/Validate.php +++ b/src/new/var/plugins/System/PSC/FriendlyCaptcha/Api/Validate.php @@ -2,7 +2,6 @@ namespace Plugin\System\PSC\FriendlyCaptcha\Api; - use Nelmio\ApiDocBundle\Annotation\Model; use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\RequestBody; @@ -10,30 +9,30 @@ use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use phpDocumentor\Reflection\Types\Boolean; use Plugin\System\PSC\FriendlyCaptcha\Dto\Input; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpClient\Exception\ClientException; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Contracts\HttpClient\HttpClientInterface; class Validate extends AbstractController { + public function __construct( + private readonly \PSC\System\SettingsBundle\Service\Shop $shopService, + private readonly HttpClientInterface $client, + ) {} - public function __construct(private readonly \PSC\System\SettingsBundle\Service\Shop $shopService, private readonly HttpClientInterface $client) - { - - } - - #[RequestBody(description: 'contact',content: new JsonContent(ref: new Model(type: Input::class)))] - #[Response(response: 200, description: 'validate token', content: new JsonContent(ref: new Model(type: Boolean::class)))] - #[ParamConverter('data', class: Input::class, converter: 'psc_rest.request_body')] - + #[RequestBody(description: 'contact', content: new JsonContent(ref: new Model(type: Input::class)))] + #[Response( + response: 200, + description: 'validate token', + content: new JsonContent(ref: new Model(type: Boolean::class)), + )] #[Tag('Plugin/System/PSC/FriendlyCaptcha')] #[Route(path: '/validate', methods: ['POST'])] - public function validate(Input $data): JsonResponse + public function validate(#[MapRequestPayload] Input $data): JsonResponse { - $shop = $this->shopService->getMongoShopByUid($this->shopService->getShopByUid($data->shop_uuid)->getUID()); try { @@ -41,16 +40,15 @@ class Validate extends AbstractController 'body' => [ 'solution' => $data->token, 'sitekey' => $shop->getPluginSettingModule('friendlycaptcha', 'sitekey'), - 'secret' => $shop->getPluginSettingModule('friendlycaptcha', 'secret') + 'secret' => $shop->getPluginSettingModule('friendlycaptcha', 'secret'), ], ]); - }catch(ClientException $e) { - if($e->getCode() == 400) { + } catch (ClientException $e) { + if ($e->getCode() == 400) { return new JsonResponse(['success' => false]); } } return new JsonResponse(json_decode($response->getContent(), true)); - } } diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Config.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Config.php index 0d95f221f..71fab1367 100644 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Config.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Config.php @@ -16,8 +16,8 @@ use PSC\Library\Calc\PaperContainer; use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; use PSC\System\SettingsBundle\Service\PaperDB; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -40,12 +40,7 @@ class Config extends AbstractController #[RequestBody(content: new JsonContent(ref: new Model(type: PriceInput::class)))] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Route(path: '/product/config', methods: ['POST'])] - #[ParamConverter( - 'data', - class: '\Plugin\System\PSC\XmlCalc\Dto\Input\PriceInput', - converter: 'psc_rest.request_body', - )] - public function config(PriceInput $data) + public function config(#[MapRequestPayload] PriceInput $data) { $product = $this->entityManager ->getRepository('PSC\Shop\EntityBundle\Entity\Product') diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Design.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Design.php index a9d09d9af..912910e54 100644 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Design.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Design.php @@ -11,16 +11,13 @@ use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput; use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct; -use PSC\Component\ApiBundle\Dto\Error\NotFound; use PSC\Library\Calc\Engine; use PSC\Library\Calc\PaperContainer; use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; -use PSC\Shop\EntityBundle\Entity\Product; use PSC\System\SettingsBundle\Service\PaperDB; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -43,12 +40,7 @@ class Design extends AbstractController #[RequestBody(content: new JsonContent(ref: new Model(type: DesignInput::class)))] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Route(path: '/product/design', methods: ['POST'])] - #[ParamConverter( - 'data', - class: '\Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput', - converter: 'psc_rest.request_body', - )] - public function config(DesignInput $data) + public function config(#[MapRequestPayload] DesignInput $data) { $product = $this->entityManager ->getRepository('PSC\Shop\EntityBundle\Entity\Product') diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Json.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Json.php index 73b5bf074..fd88ed1c9 100644 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Json.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Json.php @@ -11,16 +11,13 @@ use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use Plugin\System\PSC\XmlCalc\Dto\Input\JsonInput; use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct; -use PSC\Component\ApiBundle\Dto\Error\NotFound; use PSC\Library\Calc\Engine; use PSC\Library\Calc\PaperContainer; use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; -use PSC\Shop\EntityBundle\Entity\Product; use PSC\System\SettingsBundle\Service\PaperDB; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -43,12 +40,7 @@ class Json extends AbstractController #[RequestBody(content: new JsonContent(ref: new Model(type: JsonInput::class)))] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Route(path: '/product/json', methods: ['POST'])] - #[ParamConverter( - 'data', - class: '\Plugin\System\PSC\XmlCalc\Dto\Input\JsonInput', - converter: 'psc_rest.request_body', - )] - public function jsonApi(JsonInput $data) + public function jsonApi(#[MapRequestPayload] JsonInput $data) { $product = $this->entityManager ->getRepository('PSC\Shop\EntityBundle\Entity\Product') diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/One.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/One.php index 97e228aa5..9f806a12d 100755 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/One.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/One.php @@ -3,25 +3,27 @@ namespace Plugin\System\PSC\XmlCalc\Api\Product; use Doctrine\ORM\EntityManagerInterface; +use Nelmio\ApiDocBundle\Annotation\Model; +use Nelmio\ApiDocBundle\Annotation\Security; +use OpenApi\Annotations as OA; +use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct; use PSC\Component\ApiBundle\Dto\Error\NotFound; use PSC\Shop\EntityBundle\Entity\Product; use PSC\System\SettingsBundle\Service\Shop; -use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\Routing\Annotation\Route; -use OpenApi\Annotations as OA; -use Nelmio\ApiDocBundle\Annotation\Model; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; -use Nelmio\ApiDocBundle\Annotation\Security; -class One extends AbstractController { +class One extends AbstractController +{ private EntityManagerInterface $entityManager; public function __construct(EntityManagerInterface $entityManager) { - $this->entityManager = $entityManager; + $this->entityManager = $entityManager; } + /** * get special product * @@ -38,11 +40,11 @@ class One extends AbstractController { public function one(string $uuid): JsonResponse { $product = $this->entityManager->getRepository(Product::class)->findOneBy(['uuid' => $uuid]); - if($product) { + if ($product) { $output = new PluginProduct(); $output->calcXml = $product->getCalcXml(); - }else{ - $output = new NotFound("product not found"); + } else { + $output = new NotFound('product not found'); } return $this->json($output); } diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Preview.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Preview.php index 8439450e3..99ce0cbfd 100644 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Preview.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Preview.php @@ -34,6 +34,7 @@ use PSC\System\SettingsBundle\Service\Help; use PSC\System\SettingsBundle\Service\PaperDB; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -84,12 +85,7 @@ class Preview extends AbstractController #[RequestBody(content: new JsonContent(ref: new Model(type: PriceInput::class)))] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Price')] #[Route(path: '/product/preview', methods: ['POST'])] - #[ParamConverter( - 'data', - class: '\Plugin\System\PSC\XmlCalc\Dto\Input\PriceInput', - converter: 'psc_rest.request_body', - )] - public function preview(PriceInput $data) + public function preview(#[MapRequestPayload] PriceInput $data) { $output = new \Plugin\System\PSC\XmlCalc\Dto\Output\PriceOutput(); $output->product = $data->product; diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/PreviewDesigner.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/PreviewDesigner.php index d9266cf9d..c1925ea53 100644 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/PreviewDesigner.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/PreviewDesigner.php @@ -29,6 +29,7 @@ use PSC\System\SettingsBundle\Service\Help; use PSC\System\SettingsBundle\Service\PaperDB; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -79,8 +80,7 @@ class PreviewDesigner extends AbstractController )] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Price')] #[RequestBody(content: new JsonContent(ref: new Model(type: PDInput::class)))] - #[ParamConverter('data', class: '\Plugin\System\PSC\XmlCalc\Dto\Input\PDInput', converter: 'psc_rest.request_body')] - public function preview(PDInput $data) + public function preview(#[MapRequestPayload] PDInput $data) { $output = new \Plugin\System\PSC\XmlCalc\Dto\Output\Product\PDOutput(); diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Update.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Update.php index d2f89071c..5531d31f3 100755 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Update.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/Update.php @@ -12,11 +12,12 @@ use OpenApi\Attributes\Tag; use Plugin\System\PSC\XmlCalc\Model\Product; use PSC\Component\ApiBundle\Dto\Error\NotFound; use PSC\Shop\EntityBundle\Entity\Product as PSCProduct; -use Symfony\Component\Security\Http\Attribute\IsGranted; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; class Update extends AbstractController { @@ -36,13 +37,8 @@ class Update extends AbstractController #[RequestBody(content: new JsonContent(ref: new Model(type: Product::class)))] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Route(path: '/product/{uuid}', methods: ['PUT'])] - #[ParamConverter( - 'productObj', - class: '\Plugin\System\PSC\XmlCalc\Model\Product', - converter: 'psc_rest.request_body', - )] #[IsGranted('ROLE_USER')] - public function update(string $uuid, Product $productObj): JsonResponse + public function update(string $uuid, #[MapRequestPayload] Product $productObj): JsonResponse { $product = $this->entityManager->getRepository(PSCProduct::class)->findOneBy(['uuid' => $uuid]); diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/XML.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/XML.php index 9fe40e3d1..1640e0bab 100644 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/XML.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Product/XML.php @@ -18,9 +18,9 @@ use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; use PSC\Shop\EntityBundle\Entity\Product; use PSC\System\SettingsBundle\Service\PaperDB; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -43,12 +43,7 @@ class XML extends AbstractController #[RequestBody(content: new JsonContent(ref: new Model(type: XMLInput::class)))] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Route(path: '/product/xml', methods: ['POST'])] - #[ParamConverter( - 'data', - class: '\Plugin\System\PSC\XmlCalc\Dto\Input\XMLInput', - converter: 'psc_rest.request_body', - )] - public function xml(XMLInput $data) + public function xml(#[MapRequestPayload] XMLInput $data) { $product = $this->entityManager ->getRepository('PSC\Shop\EntityBundle\Entity\Product') diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/Shop/Update.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/Shop/Update.php index 7ff1f0b43..da2a0aba3 100755 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/Shop/Update.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/Shop/Update.php @@ -2,22 +2,23 @@ namespace Plugin\System\PSC\XmlCalc\Api\Shop; -use PSC\Shop\EntityBundle\Entity\Shop as PSCShop; -use Plugin\System\PSC\XmlCalc\Model\Shop; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Doctrine\ORM\EntityManagerInterface; +use Nelmio\ApiDocBundle\Annotation\Model; +use Nelmio\ApiDocBundle\Annotation\Security; +use OpenApi\Annotations as OA; +use Plugin\System\PSC\XmlCalc\Model\Shop; use PSC\Component\ApiBundle\Dto\Error\NotFound; +use PSC\Shop\EntityBundle\Entity\Shop as PSCShop; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; -use Nelmio\ApiDocBundle\Annotation\Security; -use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Annotation\Route; -use OpenApi\Annotations as OA; -use Nelmio\ApiDocBundle\Annotation\Model; - -class Update extends AbstractController { +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; +use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; +class Update extends AbstractController +{ private EntityManagerInterface $entityManager; public function __construct(EntityManagerInterface $entityManager) @@ -41,36 +42,33 @@ class Update extends AbstractController { * @Security(name="Bearer") */ #[Route(path: '/shop/{uuid}', methods: ['PUT'])] - #[ParamConverter('shopObj', class: '\Plugin\System\PSC\XmlCalc\Model\Shop', converter: 'psc_rest.request_body')] #[IsGranted('ROLE_USER')] - public function update(string $uuid, Shop $shopObj): JsonResponse + public function update(string $uuid, #[MapRequestPayload] Shop $shopObj): JsonResponse { $shop = $this->entityManager->getRepository(PSCShop::class)->findOneBy(['uuid' => $uuid]); - if(!$shop) { + if (!$shop) { $shop = $this->entityManager->getRepository(PSCShop::class)->findOneBy(['uid' => $uuid]); } - if(!$shop) { + if (!$shop) { return $this->json(new NotFound('shop not found')); } - - if($shopObj->formel !== null) { + + if ($shopObj->formel !== null) { $shop->setFormel($shopObj->formel); } - if($shopObj->formelTest !== null) { + if ($shopObj->formelTest !== null) { $shop->setTestFormel($shopObj->formelTest); } - if($shopObj->parameter !== null) { + if ($shopObj->parameter !== null) { $shop->setParameter($shopObj->parameter); } - if($shopObj->parameterTest !== null) { + if ($shopObj->parameterTest !== null) { $shop->setTestParameter($shopObj->parameterTest); } - $this->entityManager->persist($shop); $this->entityManager->flush(); return $this->json($shopObj); } - } diff --git a/src/new/var/plugins/System/PSC/XmlCalc/Api/System/Update.php b/src/new/var/plugins/System/PSC/XmlCalc/Api/System/Update.php index 4516f067b..50dbf204a 100755 --- a/src/new/var/plugins/System/PSC/XmlCalc/Api/System/Update.php +++ b/src/new/var/plugins/System/PSC/XmlCalc/Api/System/Update.php @@ -2,22 +2,24 @@ namespace Plugin\System\PSC\XmlCalc\Api\System; -use PSC\Shop\EntityBundle\Entity\Install; -use Plugin\System\PSC\XmlCalc\Model\System; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Doctrine\ORM\EntityManagerInterface; +use Nelmio\ApiDocBundle\Annotation\Model; +use Nelmio\ApiDocBundle\Annotation\Security; +use OpenApi\Annotations as OA; +use OpenApi\Attributes\Tag; +use Plugin\System\PSC\XmlCalc\Model\System; use PSC\Component\ApiBundle\Dto\Error\NotFound; +use PSC\Shop\EntityBundle\Entity\Install; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; -use Nelmio\ApiDocBundle\Annotation\Security; -use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Annotation\Route; -use OpenApi\Annotations as OA; -use Nelmio\ApiDocBundle\Annotation\Model; - -class Update extends AbstractController { +use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; +use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; +class Update extends AbstractController +{ private EntityManagerInterface $entityManager; public function __construct(EntityManagerInterface $entityManager) @@ -37,24 +39,23 @@ class Update extends AbstractController { * description="This is a request body", * @Model(type=\Plugin\System\PSC\XmlCalc\Model\System::class) * ) - * @OA\Tag(name="Plugin/System/psc/Xmlcalc/System") - * @Security(name="Bearer") */ #[Route(path: '/system', methods: ['PUT'])] - #[ParamConverter('systemObj', class: '\Plugin\System\PSC\XmlCalc\Model\System', converter: 'psc_rest.request_body')] #[IsGranted('ROLE_USER')] - public function update(System $systemObj): JsonResponse + #[Tag('Plugin/System/psc/Xmlcalc/System')] + #[Security(name: 'Bearer')] + public function update(#[MapRequestPayload] System $systemObj): JsonResponse { $system = $this->entityManager->getRepository(Install::class)->findOneBy(['uid' => 1]); - if(!$system) { + if (!$system) { return $this->json(new NotFound('system not found')); } - - if($systemObj->calcTemplates !== null) { + + if ($systemObj->calcTemplates !== null) { $system->setCalcTemplates($systemObj->calcTemplates); } - if($systemObj->calcTemplatesTest !== null) { + if ($systemObj->calcTemplatesTest !== null) { $system->setCalcTemplatesTest($systemObj->calcTemplatesTest); } @@ -63,5 +64,4 @@ class Update extends AbstractController { return $this->json($systemObj); } - } diff --git a/src/new/version.yaml b/src/new/version.yaml index d8ef14689..a900663aa 100755 --- a/src/new/version.yaml +++ b/src/new/version.yaml @@ -1,3 +1,3 @@ info: - datum: 21.06.2024 + datum: 16.12.2025 release: 2.3 diff --git a/src/old/application/design/vorlagen/bootstrap4_api/articletemplates/scripts/6.phtml b/src/old/application/design/vorlagen/bootstrap4_api/articletemplates/scripts/6.phtml index 1e18984bb..36e65dd41 100755 --- a/src/old/application/design/vorlagen/bootstrap4_api/articletemplates/scripts/6.phtml +++ b/src/old/application/design/vorlagen/bootstrap4_api/articletemplates/scripts/6.phtml @@ -1434,7 +1434,7 @@ if ($teile[5] == '') {