Fixes
Some checks failed
Gitea Actions / Run-Tests-On-Amd64 (push) Failing after 40m13s
Gitea Actions / Merge (push) Successful in 6m14s
Gitea Actions / Run-Tests-On-Arm64 (push) Has been cancelled

This commit is contained in:
Thomas Peterson 2025-12-16 12:38:53 +01:00
parent 1cc2bc57ba
commit 7e7628bbd3
34 changed files with 512 additions and 239 deletions

View File

@ -2114,7 +2114,7 @@ CREATE TABLE `shop` (
`smtphostname` varchar(255) DEFAULT NULL, `smtphostname` varchar(255) DEFAULT NULL,
`smtpusername` varchar(255) DEFAULT NULL, `smtpusername` varchar(255) DEFAULT NULL,
`smtppassword` 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, `useemailaslogin` int(1) NOT NULL,
`noverify` int(1) NOT NULL, `noverify` int(1) NOT NULL,
`keywords` longtext DEFAULT NULL, `keywords` longtext DEFAULT NULL,

View File

@ -5,7 +5,14 @@ declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void { 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'],
]]]);
}; };

View File

@ -2457,7 +2457,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
* length?: scalar|null, // Default: 5 * length?: scalar|null, // Default: 5
* width?: scalar|null, // Default: 130 * width?: scalar|null, // Default: 130
* height?: scalar|null, // Default: 50 * 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 * keep_value?: scalar|null, // Default: false
* charset?: scalar|null, // Default: "abcdefhjkmnprstuvwxyz23456789" * charset?: scalar|null, // Default: "abcdefhjkmnprstuvwxyz23456789"
* as_file?: scalar|null, // Default: false * as_file?: scalar|null, // Default: false

View File

@ -9,7 +9,7 @@ PSC\Shop\EntityBundle\Entity\Voucher:
code: 5f code: 5f
mode: 1 mode: 1
fromDate: <(new DateTime("2023-12-12"))> fromDate: <(new DateTime("2023-12-12"))>
toDate: <(new DateTime("2025-12-12"))> toDate: <(new DateTime("2026-12-12"))>
value: 5 value: 5
shop: '@shop_1' shop: '@shop_1'
voucher_2: voucher_2:
@ -22,7 +22,7 @@ PSC\Shop\EntityBundle\Entity\Voucher:
code: 5p code: 5p
mode: 1 mode: 1
fromDate: <(new DateTime("2023-12-12"))> fromDate: <(new DateTime("2023-12-12"))>
toDate: <(new DateTime("2025-12-12"))> toDate: <(new DateTime("2026-12-12"))>
value: 5 value: 5
shop: '@shop_1' shop: '@shop_1'
voucher_3: voucher_3:
@ -37,7 +37,7 @@ PSC\Shop\EntityBundle\Entity\Voucher:
zeroShipping: false zeroShipping: false
mode: 1 mode: 1
fromDate: <(new DateTime("2023-12-12"))> fromDate: <(new DateTime("2023-12-12"))>
toDate: <(new DateTime("2025-12-12"))> toDate: <(new DateTime("2026-12-12"))>
value: 0 value: 0
shop: '@shop_1' shop: '@shop_1'
voucher_4: voucher_4:
@ -52,7 +52,7 @@ PSC\Shop\EntityBundle\Entity\Voucher:
zeroShipping: true zeroShipping: true
mode: 1 mode: 1
fromDate: <(new DateTime("2023-12-12"))> fromDate: <(new DateTime("2023-12-12"))>
toDate: <(new DateTime("2025-12-12"))> toDate: <(new DateTime("2026-12-12"))>
value: 0 value: 0
shop: '@shop_1' shop: '@shop_1'

View File

@ -1780,7 +1780,7 @@ CREATE TABLE `shop` (
`smtphostname` varchar(255) NOT NULL, `smtphostname` varchar(255) NOT NULL,
`smtpusername` varchar(255) NOT NULL, `smtpusername` varchar(255) NOT NULL,
`smtppassword` 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, `useemailaslogin` int(1) NOT NULL,
`noverify` int(1) NOT NULL, `noverify` int(1) NOT NULL,
`keywords` longtext, `keywords` longtext,

View File

@ -19,17 +19,11 @@ use PSC\Shop\EntityBundle\Entity\Domain;
use PSC\System\SettingsBundle\Service\Shop; use PSC\System\SettingsBundle\Service\Shop;
use Symfony\Bridge\Twig\Attribute\Template; use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
/**
* ShopController fürs ProductionBundle
*
* @package PSC\Backend\Production
* @subpackage Controller
*/
class ShopController extends AbstractController class ShopController extends AbstractController
{ {
#[IsGranted('ROLE_SHOP')] #[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')] #[IsGranted('ROLE_SHOP')]
#[Route(path: '/shop/change/{shop_uuid}', name: 'psc_backend_dashboard_shop_change')] #[Route(path: '/shop/change/{shop_uuid}', name: 'psc_backend_dashboard_shop_change')]
public function changeShopAction( public function changeShopAction(Request $request, EntityManagerInterface $em, Security $security, $shop_uuid)
Request $request, {
EntityManagerInterface $em,
\Symfony\Component\Security\Core\Security $security,
$shop_uuid,
) {
$em->getRepository('PSC\Shop\EntityBundle\Entity\ShopContact')->changeSelectedShop( $em->getRepository('PSC\Shop\EntityBundle\Entity\ShopContact')->changeSelectedShop(
$security->getUser(), $security->getUser(),
$shop_uuid, $shop_uuid,
@ -114,23 +94,12 @@ class ShopController extends AbstractController
return $this->redirect($this->generateUrl('psc_backend_dashboard_index')); 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')] #[IsGranted('ROLE_SHOP')]
#[Route(path: '/shop/deleted/toogle', name: 'psc_backend_dashboard_toogle_deleted_shop')] #[Route(path: '/shop/deleted/toogle', name: 'psc_backend_dashboard_toogle_deleted_shop')]
public function toogleDisplayDeletedShopAction( public function toogleDisplayDeletedShopAction(
Request $request, Request $request,
EntityManagerInterface $em, EntityManagerInterface $em,
\Symfony\Component\Security\Core\Security $security, Security $security,
Shop $shopService, Shop $shopService,
) { ) {
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */

View File

@ -5,6 +5,7 @@ namespace PSC\Shop\OrderBundle\Normalizer;
use BadMethodCallException; use BadMethodCallException;
use PSC\Shop\OrderBundle\Model\Order\Position\IProductTypeObject; use PSC\Shop\OrderBundle\Model\Order\Position\IProductTypeObject;
use PSC\System\PluginBundle\Service\ProductType; use PSC\System\PluginBundle\Service\ProductType;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
@ -45,6 +46,6 @@ class SpecialProductDenormalizer implements DenormalizerInterface, DenormalizerA
public function getSupportedTypes(null|string $format): array public function getSupportedTypes(null|string $format): array
{ {
return [IProductTypeObject::class]; return [IProductTypeObject::class => true];
} }
} }

View File

@ -34,3 +34,7 @@ services:
PSC\Shop\OrderBundle\Api\Position\GetPluginListDisplay: PSC\Shop\OrderBundle\Api\Position\GetPluginListDisplay:
arguments: arguments:
- !tagged_iterator order.backend.list.position - !tagged_iterator order.backend.list.position
PSC\Shop\OrderBundle\Normalizer\SpecialProductDenormalizer:
tags:
- { name: serializer.normalizer, priority: 1000 }

View File

@ -8,18 +8,18 @@ use PSC\Shop\VoucherBundle\Model\Voucher as PSCVoucher;
class Voucher 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); $voucherEntity = $this->voucherRepository->findByCodeForActDate($code, $shop);
if($voucherEntity) { if ($voucherEntity) {
$v = new PSCVoucher(); $v = new PSCVoucher();
$v->setMore($voucherEntity->isMore()); $v->setMore($voucherEntity->isMore());
$v->setCode($code); $v->setCode($code);
if($voucherEntity->isPercent()) { if ($voucherEntity->isPercent()) {
$v->setPercentValue($voucherEntity->getValue()); $v->setPercentValue($voucherEntity->getValue());
} else { } else {
$v->setValueInCent($voucherEntity->getValue() * 100); $v->setValueInCent($voucherEntity->getValue() * 100);

View File

@ -11,9 +11,9 @@ use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag; use OpenApi\Attributes\Tag;
use PSC\System\SettingsBundle\Model\Papercontainer; use PSC\System\SettingsBundle\Model\Papercontainer;
use PSC\System\SettingsBundle\Service\Shop; use PSC\System\SettingsBundle\Service\Shop;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
@ -39,7 +39,7 @@ class Update extends AbstractController
#[Route(path: '/papercontainer', methods: ['PUT'])] #[Route(path: '/papercontainer', methods: ['PUT'])]
#[RequestBody(content: new JsonContent(ref: new Model(type: Papercontainer::class)))] #[RequestBody(content: new JsonContent(ref: new Model(type: Papercontainer::class)))]
#[IsGranted('ROLE_USER')] #[IsGranted('ROLE_USER')]
public function updatePapercontainer(Papercontainer $papercontainer): JsonResponse public function updatePapercontainer(#[MapRequestPayload] Papercontainer $papercontainer): JsonResponse
{ {
$install = $this->shopService->getShopByDomain()->getInstall(); $install = $this->shopService->getShopByDomain()->getInstall();
$install->setPaperContainer($papercontainer->getContent()); $install->setPaperContainer($papercontainer->getContent());

View File

@ -2,10 +2,10 @@
namespace Tests\PSC\Shop\Contact\Api; namespace Tests\PSC\Shop\Contact\Api;
use Tests\RefreshDatabaseTrait;
use PSC\Shop\ContactBundle\Repository\ContactRepository; use PSC\Shop\ContactBundle\Repository\ContactRepository;
use PSC\Shop\EntityBundle\Repository\ShopRepository; use PSC\Shop\EntityBundle\Repository\ShopRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Tests\RefreshDatabaseTrait;
class AllTest extends WebTestCase class AllTest extends WebTestCase
{ {
@ -26,9 +26,8 @@ class AllTest extends WebTestCase
$data = json_decode($client->getResponse()->getContent(), true); $data = json_decode($client->getResponse()->getContent(), true);
self::assertSame(3, count($data['data'])); self::assertSame(3, count($data['data']));
self::assertSame("test3@shop.de", $data['data'][0]['email']); self::assertSame('test3@shop.de', $data['data'][1]['email']);
self::assertSame("test@shop.de", $data['data'][1]['email']); self::assertSame('test@shop.de', $data['data'][0]['email']);
self::assertSame("admin@shop.de", $data['data'][2]['email']); self::assertSame('admin@shop.de', $data['data'][2]['email']);
} }
} }

View File

@ -1,10 +1,11 @@
<?php <?php
namespace Tests\PSC\Shop\Payment\Controller; namespace Tests\PSC\Shop\Payment\Controller;
use Tests\RefreshDatabaseTrait;
use PSC\Shop\ContactBundle\Repository\ContactRepository; use PSC\Shop\ContactBundle\Repository\ContactRepository;
use PSC\Shop\EntityBundle\Repository\ShopRepository; use PSC\Shop\EntityBundle\Repository\ShopRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Tests\RefreshDatabaseTrait;
class ListTest extends WebTestCase class ListTest extends WebTestCase
{ {
@ -27,7 +28,7 @@ class ListTest extends WebTestCase
$crawler = $client->request('GET', '/backend/payment/list/index'); $crawler = $client->request('GET', '/backend/payment/list/index');
$this->assertResponseIsSuccessful(); $this->assertResponseIsSuccessful();
$crawler = $crawler->filter('.table > tbody > tr'); $crawler = $crawler->filter('table > tbody > tr');
$this->assertSame(4, $crawler->count()); $this->assertSame(4, $crawler->count());
} }
} }

View File

@ -20,11 +20,7 @@ class ListTest extends PantherTestCase
$chromeOptions->addArguments(['--window-size=1200,1100', '--disable-gpu']); $chromeOptions->addArguments(['--window-size=1200,1100', '--disable-gpu']);
$capabilities = DesiredCapabilities::chrome(); $capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); $capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions);
$this->client = Client::createSeleniumClient( $this->client = Client::createSeleniumClient('http://chrome:4444', $capabilities, 'http://application:9001');
'http://chrome:4444',
$capabilities,
'http://application:9001'
);
static::startWebServer(['hostname' => 'application']); static::startWebServer(['hostname' => 'application']);
} }
@ -40,9 +36,20 @@ class ListTest extends PantherTestCase
$this->client->get('/backend/login'); $this->client->get('/backend/login');
$crawler = $this->client->submitForm('login', ['username' => 'admin@shop.de', 'password' => 'shop2014']); $crawler = $this->client->submitForm('login', ['username' => 'admin@shop.de', 'password' => 'shop2014']);
$crawler = $this->client->get('/backend/dashboard'); $crawler = $this->client->get('/backend/dashboard');
self::assertSame('Dashboard', $this->client->getCrawler()->filter('h1')->text()); self::assertSame(
'Dashboard',
$this->client
->getCrawler()
->filter('h1')
->text(),
);
$crawler = $this->client->clickLink('Zahlarten'); $crawler = $this->client->clickLink('Zahlarten');
self::assertStringContainsString('Zahlarten', $this->client->getCrawler()->filter('h3')->text()); self::assertStringContainsString(
'Zahlarten',
$this->client
->getCrawler()
->filter('h1')
->text(),
);
} }
} }

View File

@ -1,10 +1,11 @@
<?php <?php
namespace App\Tests\PSC\Shop\Shipping\Controller; namespace App\Tests\PSC\Shop\Shipping\Controller;
use Tests\RefreshDatabaseTrait;
use PSC\Shop\ContactBundle\Repository\ContactRepository; use PSC\Shop\ContactBundle\Repository\ContactRepository;
use PSC\Shop\EntityBundle\Repository\ShopRepository; use PSC\Shop\EntityBundle\Repository\ShopRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Tests\RefreshDatabaseTrait;
class ListTest extends WebTestCase class ListTest extends WebTestCase
{ {
@ -27,7 +28,8 @@ class ListTest extends WebTestCase
$crawler = $client->request('GET', '/backend/shipping/list/index'); $crawler = $client->request('GET', '/backend/shipping/list/index');
$this->assertResponseIsSuccessful(); $this->assertResponseIsSuccessful();
$crawler = $crawler->filter('.table > tbody > tr'); $crawler = $crawler->filter('table > tbody > tr');
$this->assertSame(4, $crawler->count()); $this->assertSame(4, $crawler->count());
} }
} }

View File

@ -2114,7 +2114,7 @@ CREATE TABLE `shop` (
`smtphostname` varchar(255) DEFAULT NULL, `smtphostname` varchar(255) DEFAULT NULL,
`smtpusername` varchar(255) DEFAULT NULL, `smtpusername` varchar(255) DEFAULT NULL,
`smtppassword` varchar(255) DEFAULT NULL, `smtppassword` varchar(255) DEFAULT NULL,
`smtpusethis` int(1) NOT NULL, `smtpusethis` int(1) DEFAULT 0,
`useemailaslogin` int(1) NOT NULL, `useemailaslogin` int(1) NOT NULL,
`noverify` int(1) NOT NULL, `noverify` int(1) NOT NULL,
`keywords` longtext DEFAULT NULL, `keywords` longtext DEFAULT NULL,

View File

@ -2110,7 +2110,7 @@ CREATE TABLE `shop` (
`smtphostname` varchar(255) DEFAULT NULL, `smtphostname` varchar(255) DEFAULT NULL,
`smtpusername` varchar(255) DEFAULT NULL, `smtpusername` varchar(255) DEFAULT NULL,
`smtppassword` 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, `useemailaslogin` int(1) NOT NULL,
`noverify` int(1) NOT NULL, `noverify` int(1) NOT NULL,
`keywords` longtext DEFAULT NULL, `keywords` longtext DEFAULT NULL,

View File

@ -5,15 +5,14 @@ namespace Plugin\Custom\PSC\FormBuilder\Api\Layout;
use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\DocumentManager;
use Nelmio\ApiDocBundle\Attribute\Model; use Nelmio\ApiDocBundle\Attribute\Model;
use Nelmio\ApiDocBundle\Attribute\Security; use Nelmio\ApiDocBundle\Attribute\Security;
use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\RequestBody;
use OpenApi\Attributes\Response; use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag; use OpenApi\Attributes\Tag;
use Plugin\Custom\PSC\FormBuilder\Document\Layout as PSCLayout; use Plugin\Custom\PSC\FormBuilder\Document\Layout as PSCLayout;
use Plugin\Custom\PSC\FormBuilder\Dto\Layout\Input; use Plugin\Custom\PSC\FormBuilder\Dto\Layout\Input;
use Plugin\Custom\PSC\FormBuilder\Model\Layout; use Plugin\Custom\PSC\FormBuilder\Model\Layout;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
@ -27,10 +26,9 @@ class Add extends AbstractController
#[Route(path: '/layouts/add', methods: ['POST'])] #[Route(path: '/layouts/add', methods: ['POST'])]
#[Tag('FormBuilder')] #[Tag('FormBuilder')]
#[RequestBody(content: new Model(type: Input::class))] #[RequestBody(content: new Model(type: Input::class))]
#[ParamConverter('data', class: Input::class, converter: 'psc_rest.request_body')]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
#[Security(name: 'Security')] #[Security(name: 'Security')]
public function add(Input $data) public function add(#[MapRequestPayload] Input $data)
{ {
$layout = new PSCLayout(); $layout = new PSCLayout();
$layout->setTitle($data->title); $layout->setTitle($data->title);

View File

@ -0,0 +1,64 @@
<?php
namespace Plugin\Custom\PSC\LaufkartenLayouter\Api;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\EntityManagerInterface;
use MongoDB\BSON\ObjectId;
use OpenApi\Attributes\Parameter;
use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag;
use PSC\Shop\EntityBundle\Entity\Layoutdesigndata;
use PSC\Shop\MediaBundle\Document\Media;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
class Load
{
#[Response(response: 200, description: 'loaded successfully')]
#[Response(response: 404, description: 'Layouter session not found')]
#[Route('/load/{layouterUUId}', name: 'plugin_custom_psc_laufkartenlayouter_load', methods: ['GET'])]
#[Tag(name: 'Plugin/Custom/PSC/LaufkartenLayouter')]
#[Parameter(name: 'layouterUUId', in: 'path', required: true, description: 'Layouter UUID')]
public function loadAction(
string $layouterUUId,
EntityManagerInterface $entityManager,
DocumentManager $documentManager,
): JsonResponse {
/** @var Layoutdesigndata|null $layoutDesignData */
$layoutDesignData = $entityManager
->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,
]);
}
}

View File

@ -19,17 +19,25 @@ class Save
#[Tag(name: 'Plugin/Custom/PSC/LaufkartenLayouter')] #[Tag(name: 'Plugin/Custom/PSC/LaufkartenLayouter')]
public function saveAction(#[MapRequestPayload] Input $data, EntityManagerInterface $entityManager): JsonResponse public function saveAction(#[MapRequestPayload] Input $data, EntityManagerInterface $entityManager): JsonResponse
{ {
// 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 = new Layoutdesigndata();
$layoutDesignData->setUuid($data->layouterUUId); $layoutDesignData->setUuid($data->layouterUUId);
$layoutDesignData->setArticleUuid($data->productUUId); $layoutDesignData->setArticleUuid($data->productUUId);
$layoutDesignData->setDesign(['files' => $data->files]); $layoutDesignData->setDesign(['files' => $data->files]);
$entityManager->persist($layoutDesignData); $entityManager->persist($layoutDesignData);
}
$entityManager->flush(); $entityManager->flush();
$json = new JsonResponse(); return new JsonResponse(['success' => true]);
$json->setContent(json_encode(['success' => true]));
return $json;
} }
} }

View File

@ -212,10 +212,96 @@
let pdfData = []; let pdfData = [];
let thumbnails = {}; let thumbnails = {};
let ocrPreviews = {}; let ocrPreviews = {};
const layouterUUId = '{{ layouterUUId }}';
const isEditMode = layouterUUId && layouterUUId !== '';
// Initialize PDF.js // Initialize PDF.js
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.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 // Save current form values
function saveCurrentFormValues() { function saveCurrentFormValues() {
if (currentStep === 2 && pdfData.length > 0) { if (currentStep === 2 && pdfData.length > 0) {
@ -233,7 +319,7 @@
} }
// Step navigation // Step navigation
function goToStep(step) { async function goToStep(step) {
// Save current values before switching // Save current values before switching
saveCurrentFormValues(); saveCurrentFormValues();
@ -262,19 +348,174 @@
currentStep = step; currentStep = step;
if (step === 2) { 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) { if (uploadedFiles.length > 0 && pdfData.length === 0) {
// First time going to step 2 // First time going to step 2 - initialize PDFs
initializePDFData(); await initializePDFData();
} else if (hasNewFiles) {
// New files were added - initialize only the new ones
await initializeNewPDFData();
} else if (pdfData.length > 0) { } else if (pdfData.length > 0) {
// Returning to step 2, refresh table with saved values // 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(); updatePDFTable();
} }
} }
}
if (step === 3) { if (step === 3) {
generateFinalSummary(); generateFinalSummary();
} }
} }
// 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 // Initialize PDF data and table
async function initializePDFData() { async function initializePDFData() {
pdfData = []; pdfData = [];
@ -316,7 +557,8 @@
isDuplex: numPages % 2 === 0 && numPages > 1, isDuplex: numPages % 2 === 0 && numPages > 1,
ocrNumber: '', ocrNumber: '',
inRed: false, inRed: false,
processed: false processed: false,
isAlreadyUploaded: false // New files need to be uploaded
}); });
// Use placeholder thumbnail initially // Use placeholder thumbnail initially
@ -844,21 +1086,30 @@
const uploadedUUIDs = []; const uploadedUUIDs = [];
for (let i = 0; i < pdfData.length; i++) { for (let i = 0; i < pdfData.length; 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})`; finishBtn.textContent = `Uploading PDFs... (${i + 1}/${pdfData.length})`;
const uploadResult = await uploadSinglePDF(pdfData[i], i); 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({ uploadedUUIDs.push({
uuid: uploadResult.uuid, uuid: uploadUuid,
fileName: pdfData[i].fileName, fileName: pdfData[i].fileName,
ocrNumber: pdfData[i].ocrNumber, ocrNumber: pdfData[i].ocrNumber,
inRed: pdfData[i].inRed, inRed: pdfData[i].inRed,
numPages: pdfData[i].numPages, numPages: pdfData[i].numPages,
isDuplex: pdfData[i].isDuplex isDuplex: pdfData[i].isDuplex
}); });
console.log(`Uploaded ${pdfData[i].fileName}: ${uploadResult.uuid}`);
} }
// Step 2: Call layouter/save with all UUIDs // Step 2: Call layouter/save with all UUIDs

View File

@ -2,7 +2,6 @@
namespace Plugin\System\PSC\CaptchaFox\Api; namespace Plugin\System\PSC\CaptchaFox\Api;
use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\RequestBody;
@ -10,30 +9,30 @@ use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag; use OpenApi\Attributes\Tag;
use phpDocumentor\Reflection\Types\Boolean; use phpDocumentor\Reflection\Types\Boolean;
use Plugin\System\PSC\FriendlyCaptcha\Dto\Input; use Plugin\System\PSC\FriendlyCaptcha\Dto\Input;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\Exception\ClientException; use Symfony\Component\HttpClient\Exception\ClientException;
use Symfony\Component\HttpFoundation\JsonResponse; 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; use Symfony\Contracts\HttpClient\HttpClientInterface;
class Validate extends AbstractController 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)),
#[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')]
#[Tag('Plugin/System/PSC/CaptchaFox')] #[Tag('Plugin/System/PSC/CaptchaFox')]
#[Route(path: '/validate', methods: ['POST'])] #[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()); $shop = $this->shopService->getMongoShopByUid($this->shopService->getShopByUid($data->shop_uuid)->getUID());
try { try {
@ -41,16 +40,15 @@ class Validate extends AbstractController
'body' => [ 'body' => [
'solution' => $data->token, 'solution' => $data->token,
'sitekey' => $shop->getPluginSettingModule('captchafox', 'sitekey'), 'sitekey' => $shop->getPluginSettingModule('captchafox', 'sitekey'),
'secret' => $shop->getPluginSettingModule('captchafox', 'secret') 'secret' => $shop->getPluginSettingModule('captchafox', 'secret'),
], ],
]); ]);
}catch(ClientException $e) { } catch (ClientException $e) {
if($e->getCode() == 400) { if ($e->getCode() == 400) {
return new JsonResponse(['success' => false]); return new JsonResponse(['success' => false]);
} }
} }
return new JsonResponse(json_decode($response->getContent(), true)); return new JsonResponse(json_decode($response->getContent(), true));
} }
} }

View File

@ -2,7 +2,6 @@
namespace Plugin\System\PSC\FriendlyCaptcha\Api; namespace Plugin\System\PSC\FriendlyCaptcha\Api;
use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\JsonContent;
use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\RequestBody;
@ -10,30 +9,30 @@ use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag; use OpenApi\Attributes\Tag;
use phpDocumentor\Reflection\Types\Boolean; use phpDocumentor\Reflection\Types\Boolean;
use Plugin\System\PSC\FriendlyCaptcha\Dto\Input; use Plugin\System\PSC\FriendlyCaptcha\Dto\Input;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\Exception\ClientException; use Symfony\Component\HttpClient\Exception\ClientException;
use Symfony\Component\HttpFoundation\JsonResponse; 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; use Symfony\Contracts\HttpClient\HttpClientInterface;
class Validate extends AbstractController 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)),
#[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')]
#[Tag('Plugin/System/PSC/FriendlyCaptcha')] #[Tag('Plugin/System/PSC/FriendlyCaptcha')]
#[Route(path: '/validate', methods: ['POST'])] #[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()); $shop = $this->shopService->getMongoShopByUid($this->shopService->getShopByUid($data->shop_uuid)->getUID());
try { try {
@ -41,16 +40,15 @@ class Validate extends AbstractController
'body' => [ 'body' => [
'solution' => $data->token, 'solution' => $data->token,
'sitekey' => $shop->getPluginSettingModule('friendlycaptcha', 'sitekey'), 'sitekey' => $shop->getPluginSettingModule('friendlycaptcha', 'sitekey'),
'secret' => $shop->getPluginSettingModule('friendlycaptcha', 'secret') 'secret' => $shop->getPluginSettingModule('friendlycaptcha', 'secret'),
], ],
]); ]);
}catch(ClientException $e) { } catch (ClientException $e) {
if($e->getCode() == 400) { if ($e->getCode() == 400) {
return new JsonResponse(['success' => false]); return new JsonResponse(['success' => false]);
} }
} }
return new JsonResponse(json_decode($response->getContent(), true)); return new JsonResponse(json_decode($response->getContent(), true));
} }
} }

View File

@ -16,8 +16,8 @@ use PSC\Library\Calc\PaperContainer;
use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Model\Contact;
use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 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)))] #[RequestBody(content: new JsonContent(ref: new Model(type: PriceInput::class)))]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')]
#[Route(path: '/product/config', methods: ['POST'])] #[Route(path: '/product/config', methods: ['POST'])]
#[ParamConverter( public function config(#[MapRequestPayload] PriceInput $data)
'data',
class: '\Plugin\System\PSC\XmlCalc\Dto\Input\PriceInput',
converter: 'psc_rest.request_body',
)]
public function config(PriceInput $data)
{ {
$product = $this->entityManager $product = $this->entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Product') ->getRepository('PSC\Shop\EntityBundle\Entity\Product')

View File

@ -11,16 +11,13 @@ use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag; use OpenApi\Attributes\Tag;
use Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput; use Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput;
use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct; 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\Engine;
use PSC\Library\Calc\PaperContainer; use PSC\Library\Calc\PaperContainer;
use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Model\Contact;
use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer;
use PSC\Shop\EntityBundle\Entity\Product;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 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\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 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)))] #[RequestBody(content: new JsonContent(ref: new Model(type: DesignInput::class)))]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')]
#[Route(path: '/product/design', methods: ['POST'])] #[Route(path: '/product/design', methods: ['POST'])]
#[ParamConverter( public function config(#[MapRequestPayload] DesignInput $data)
'data',
class: '\Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput',
converter: 'psc_rest.request_body',
)]
public function config(DesignInput $data)
{ {
$product = $this->entityManager $product = $this->entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Product') ->getRepository('PSC\Shop\EntityBundle\Entity\Product')

View File

@ -11,16 +11,13 @@ use OpenApi\Attributes\Response;
use OpenApi\Attributes\Tag; use OpenApi\Attributes\Tag;
use Plugin\System\PSC\XmlCalc\Dto\Input\JsonInput; use Plugin\System\PSC\XmlCalc\Dto\Input\JsonInput;
use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct; 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\Engine;
use PSC\Library\Calc\PaperContainer; use PSC\Library\Calc\PaperContainer;
use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Model\Contact;
use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer;
use PSC\Shop\EntityBundle\Entity\Product;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 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\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 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)))] #[RequestBody(content: new JsonContent(ref: new Model(type: JsonInput::class)))]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')]
#[Route(path: '/product/json', methods: ['POST'])] #[Route(path: '/product/json', methods: ['POST'])]
#[ParamConverter( public function jsonApi(#[MapRequestPayload] JsonInput $data)
'data',
class: '\Plugin\System\PSC\XmlCalc\Dto\Input\JsonInput',
converter: 'psc_rest.request_body',
)]
public function jsonApi(JsonInput $data)
{ {
$product = $this->entityManager $product = $this->entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Product') ->getRepository('PSC\Shop\EntityBundle\Entity\Product')

View File

@ -3,25 +3,27 @@
namespace Plugin\System\PSC\XmlCalc\Api\Product; namespace Plugin\System\PSC\XmlCalc\Api\Product;
use Doctrine\ORM\EntityManagerInterface; 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\Component\ApiBundle\Dto\Error\NotFound;
use PSC\Shop\EntityBundle\Entity\Product; use PSC\Shop\EntityBundle\Entity\Product;
use PSC\System\SettingsBundle\Service\Shop; use PSC\System\SettingsBundle\Service\Shop;
use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Attribute\Route;
use OpenApi\Annotations as OA;
use Nelmio\ApiDocBundle\Annotation\Model;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
use Nelmio\ApiDocBundle\Annotation\Security;
class One extends AbstractController { class One extends AbstractController
{
private EntityManagerInterface $entityManager; private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager) public function __construct(EntityManagerInterface $entityManager)
{ {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
} }
/** /**
* get special product * get special product
* *
@ -38,11 +40,11 @@ class One extends AbstractController {
public function one(string $uuid): JsonResponse public function one(string $uuid): JsonResponse
{ {
$product = $this->entityManager->getRepository(Product::class)->findOneBy(['uuid' => $uuid]); $product = $this->entityManager->getRepository(Product::class)->findOneBy(['uuid' => $uuid]);
if($product) { if ($product) {
$output = new PluginProduct(); $output = new PluginProduct();
$output->calcXml = $product->getCalcXml(); $output->calcXml = $product->getCalcXml();
}else{ } else {
$output = new NotFound("product not found"); $output = new NotFound('product not found');
} }
return $this->json($output); return $this->json($output);
} }

View File

@ -34,6 +34,7 @@ use PSC\System\SettingsBundle\Service\Help;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 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)))] #[RequestBody(content: new JsonContent(ref: new Model(type: PriceInput::class)))]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Price')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Price')]
#[Route(path: '/product/preview', methods: ['POST'])] #[Route(path: '/product/preview', methods: ['POST'])]
#[ParamConverter( public function preview(#[MapRequestPayload] PriceInput $data)
'data',
class: '\Plugin\System\PSC\XmlCalc\Dto\Input\PriceInput',
converter: 'psc_rest.request_body',
)]
public function preview(PriceInput $data)
{ {
$output = new \Plugin\System\PSC\XmlCalc\Dto\Output\PriceOutput(); $output = new \Plugin\System\PSC\XmlCalc\Dto\Output\PriceOutput();
$output->product = $data->product; $output->product = $data->product;

View File

@ -29,6 +29,7 @@ use PSC\System\SettingsBundle\Service\Help;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
@ -79,8 +80,7 @@ class PreviewDesigner extends AbstractController
)] )]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Price')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Price')]
#[RequestBody(content: new JsonContent(ref: new Model(type: PDInput::class)))] #[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(#[MapRequestPayload] PDInput $data)
public function preview(PDInput $data)
{ {
$output = new \Plugin\System\PSC\XmlCalc\Dto\Output\Product\PDOutput(); $output = new \Plugin\System\PSC\XmlCalc\Dto\Output\Product\PDOutput();

View File

@ -12,11 +12,12 @@ use OpenApi\Attributes\Tag;
use Plugin\System\PSC\XmlCalc\Model\Product; use Plugin\System\PSC\XmlCalc\Model\Product;
use PSC\Component\ApiBundle\Dto\Error\NotFound; use PSC\Component\ApiBundle\Dto\Error\NotFound;
use PSC\Shop\EntityBundle\Entity\Product as PSCProduct; use PSC\Shop\EntityBundle\Entity\Product as PSCProduct;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class Update extends AbstractController class Update extends AbstractController
{ {
@ -36,13 +37,8 @@ class Update extends AbstractController
#[RequestBody(content: new JsonContent(ref: new Model(type: Product::class)))] #[RequestBody(content: new JsonContent(ref: new Model(type: Product::class)))]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')]
#[Route(path: '/product/{uuid}', methods: ['PUT'])] #[Route(path: '/product/{uuid}', methods: ['PUT'])]
#[ParamConverter(
'productObj',
class: '\Plugin\System\PSC\XmlCalc\Model\Product',
converter: 'psc_rest.request_body',
)]
#[IsGranted('ROLE_USER')] #[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]); $product = $this->entityManager->getRepository(PSCProduct::class)->findOneBy(['uuid' => $uuid]);

View File

@ -18,9 +18,9 @@ use PSC\Shop\ContactBundle\Model\Contact;
use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer; use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer;
use PSC\Shop\EntityBundle\Entity\Product; use PSC\Shop\EntityBundle\Entity\Product;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 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)))] #[RequestBody(content: new JsonContent(ref: new Model(type: XMLInput::class)))]
#[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')] #[Tag(name: 'Plugin/System/psc/Xmlcalc/Product')]
#[Route(path: '/product/xml', methods: ['POST'])] #[Route(path: '/product/xml', methods: ['POST'])]
#[ParamConverter( public function xml(#[MapRequestPayload] XMLInput $data)
'data',
class: '\Plugin\System\PSC\XmlCalc\Dto\Input\XMLInput',
converter: 'psc_rest.request_body',
)]
public function xml(XMLInput $data)
{ {
$product = $this->entityManager $product = $this->entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Product') ->getRepository('PSC\Shop\EntityBundle\Entity\Product')

View File

@ -2,22 +2,23 @@
namespace Plugin\System\PSC\XmlCalc\Api\Shop; 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 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\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\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; 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\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use OpenApi\Annotations as OA; use Symfony\Component\Routing\Attribute\Route;
use Nelmio\ApiDocBundle\Annotation\Model; use Symfony\Component\Security\Http\Attribute\IsGranted;
class Update extends AbstractController {
class Update extends AbstractController
{
private EntityManagerInterface $entityManager; private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager) public function __construct(EntityManagerInterface $entityManager)
@ -41,36 +42,33 @@ class Update extends AbstractController {
* @Security(name="Bearer") * @Security(name="Bearer")
*/ */
#[Route(path: '/shop/{uuid}', methods: ['PUT'])] #[Route(path: '/shop/{uuid}', methods: ['PUT'])]
#[ParamConverter('shopObj', class: '\Plugin\System\PSC\XmlCalc\Model\Shop', converter: 'psc_rest.request_body')]
#[IsGranted('ROLE_USER')] #[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]); $shop = $this->entityManager->getRepository(PSCShop::class)->findOneBy(['uuid' => $uuid]);
if(!$shop) { if (!$shop) {
$shop = $this->entityManager->getRepository(PSCShop::class)->findOneBy(['uid' => $uuid]); $shop = $this->entityManager->getRepository(PSCShop::class)->findOneBy(['uid' => $uuid]);
} }
if(!$shop) { if (!$shop) {
return $this->json(new NotFound('shop not found')); return $this->json(new NotFound('shop not found'));
} }
if($shopObj->formel !== null) { if ($shopObj->formel !== null) {
$shop->setFormel($shopObj->formel); $shop->setFormel($shopObj->formel);
} }
if($shopObj->formelTest !== null) { if ($shopObj->formelTest !== null) {
$shop->setTestFormel($shopObj->formelTest); $shop->setTestFormel($shopObj->formelTest);
} }
if($shopObj->parameter !== null) { if ($shopObj->parameter !== null) {
$shop->setParameter($shopObj->parameter); $shop->setParameter($shopObj->parameter);
} }
if($shopObj->parameterTest !== null) { if ($shopObj->parameterTest !== null) {
$shop->setTestParameter($shopObj->parameterTest); $shop->setTestParameter($shopObj->parameterTest);
} }
$this->entityManager->persist($shop); $this->entityManager->persist($shop);
$this->entityManager->flush(); $this->entityManager->flush();
return $this->json($shopObj); return $this->json($shopObj);
} }
} }

View File

@ -2,22 +2,24 @@
namespace Plugin\System\PSC\XmlCalc\Api\System; 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 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\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\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; 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\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use OpenApi\Annotations as OA; use Symfony\Component\Routing\Attribute\Route;
use Nelmio\ApiDocBundle\Annotation\Model; use Symfony\Component\Security\Http\Attribute\IsGranted;
class Update extends AbstractController {
class Update extends AbstractController
{
private EntityManagerInterface $entityManager; private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager) public function __construct(EntityManagerInterface $entityManager)
@ -37,24 +39,23 @@ class Update extends AbstractController {
* description="This is a request body", * description="This is a request body",
* @Model(type=\Plugin\System\PSC\XmlCalc\Model\System::class) * @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'])] #[Route(path: '/system', methods: ['PUT'])]
#[ParamConverter('systemObj', class: '\Plugin\System\PSC\XmlCalc\Model\System', converter: 'psc_rest.request_body')]
#[IsGranted('ROLE_USER')] #[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]); $system = $this->entityManager->getRepository(Install::class)->findOneBy(['uid' => 1]);
if(!$system) { if (!$system) {
return $this->json(new NotFound('system not found')); return $this->json(new NotFound('system not found'));
} }
if($systemObj->calcTemplates !== null) { if ($systemObj->calcTemplates !== null) {
$system->setCalcTemplates($systemObj->calcTemplates); $system->setCalcTemplates($systemObj->calcTemplates);
} }
if($systemObj->calcTemplatesTest !== null) { if ($systemObj->calcTemplatesTest !== null) {
$system->setCalcTemplatesTest($systemObj->calcTemplatesTest); $system->setCalcTemplatesTest($systemObj->calcTemplatesTest);
} }
@ -63,5 +64,4 @@ class Update extends AbstractController {
return $this->json($systemObj); return $this->json($systemObj);
} }
} }

View File

@ -1,3 +1,3 @@
info: info:
datum: 21.06.2024 datum: 16.12.2025
release: 2.3 release: 2.3

View File

@ -1434,7 +1434,7 @@ if ($teile[5] == '') {
<div style="background-color:#eeeced;margin-bottom: 10px;padding: 5px;border:1px solid rgba(0,0,0,.2)"> <div style="background-color:#eeeced;margin-bottom: 10px;padding: 5px;border:1px solid rgba(0,0,0,.2)">
<?php if ($this->layouterPreviewId): /** Aufruf des Steplayouters (Steplayouter2) */ ?> <?php if ($this->layouterPreviewId): /** Aufruf des Steplayouters (Steplayouter2) */ ?>
<a class="btn pop_over btn-success btn-large" rel="#overlaystep" href="/apps/plugin/custom/psc/laufkartenlayouter/frontend/designer/load/<?= $this->article->uuid ?>/<?= $this->layouterPreviewId ?>"><?php echo <a class="btn pop_over btn-success btn-large" rel="#overlaystep" href="/apps/plugin/custom/psc/laufkartenlayouter/frontend/designer/start/<?= $this->article->uuid ?>/<?= $this->layouterPreviewId ?>"><?php echo
$this->translate('Zum Online-Designer') $this->translate('Zum Online-Designer')
?></a> ?></a>
<?php else: ?> <?php else: ?>