From 6255a06dbceae34869311a8ff800723422ac06b5 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:35:22 +0100 Subject: [PATCH 01/14] Extended content base twig with css and javascript --- templates/EasyAdminBundle/content.html.twig | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 templates/EasyAdminBundle/content.html.twig diff --git a/templates/EasyAdminBundle/content.html.twig b/templates/EasyAdminBundle/content.html.twig new file mode 100644 index 0000000..e69de29 From 0f6ebb895dad8cbb2b063565ab5052366c9c852d Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:36:22 +0100 Subject: [PATCH 02/14] Extended content base twig with css and javascript --- templates/EasyAdminBundle/content.html.twig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/templates/EasyAdminBundle/content.html.twig b/templates/EasyAdminBundle/content.html.twig index e69de29..1ffd45b 100644 --- a/templates/EasyAdminBundle/content.html.twig +++ b/templates/EasyAdminBundle/content.html.twig @@ -0,0 +1,11 @@ +{% extends '@EasyAdmin/page/content.html.twig' %} + +{% block head_javascript %} + {{ parent() }} + {{ encore_entry_script_tags('app') }} +{% endblock head_javascript %} + +{% block head_stylesheets %} + {{ parent() }} + {{ encore_entry_link_tags('app') }} +{% endblock head_stylesheets %} From eb74c0130485a87f51b643c8c87ea3cc3a468ff0 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:36:45 +0100 Subject: [PATCH 03/14] Updated fixtures --- src/DataFixtures/AppFixtures.php | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index 9ff6adc..abbe8d3 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -2,6 +2,7 @@ namespace App\DataFixtures; +use App\Entity\Tenant; use App\Entity\Tenant\Qr; use App\Entity\Tenant\Url; use App\Enum\QrModeEnum; @@ -12,25 +13,44 @@ class AppFixtures extends Fixture { public function load(ObjectManager $manager): void { + // Create a tenant entity + $tenant = new Tenant(); // Replace Tenant with the actual class + $tenant->setTitle('Fixture tenant'); + $tenant->setDescription('Fixture tenant description'); + $tenant->setCreatedAt(new \DateTimeImmutable()); + $tenant->setCreatedBy('fixture_author'); + $tenant->setModifiedAt(new \DateTimeImmutable()); + $tenant->setModifiedBy('fixture_author'); + $manager->persist($tenant); + $departments = [ 'Department A', 'Department B', ]; + // Create Qr entities for ($i = 0; $i < 80; ++$i) { $qr = new Qr(); - $qr->setTitle('qr '.$i); - $qr->setDepartment(0 == $i % 2 ? $departments['0'] : $departments['1']); + $qr->setTitle('qr ' . $i); + $qr->setDepartment(0 == $i % 2 ? $departments[0] : $departments[1]); $qr->setAuthor('fixture_author'); $qr->setMode(QrModeEnum::DEFAULT); + $qr->setTenant($tenant); $qr->setCreatedAt(new \DateTimeImmutable()); + $qr->setCreatedBy('fixture_author'); $qr->setModifiedAt(new \DateTimeImmutable()); + $qr->setModifiedBy('fixture_author'); $manager->persist($qr); $url = new Url(); - $url->setUrl('http://localhost/loremipsum/long_url/'.$i); + $url->setUrl('http://localhost/loremipsum/long_url/' . $i); $url->setQr($qr); + $url->setTenant($tenant); + $url->setCreatedAt(new \DateTimeImmutable()); + $url->setCreatedBy('fixture_author'); + $url->setModifiedAt(new \DateTimeImmutable()); + $url->setModifiedBy('fixture_author'); $manager->persist($url); } From 885b92dcf3d15f93ad5db70ebfdd3336b23444f6 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:38:31 +0100 Subject: [PATCH 04/14] Added app.js and app.css served through webpack --- .gitignore | 7 + assets/app.js | 104 +++++ assets/styles/app.css | 72 ++++ composer.json | 1 + composer.lock | 586 ++++++++++++++++------------ config/bundles.php | 1 + config/packages/framework.yaml | 2 + config/packages/webpack_encore.yaml | 45 +++ package.json | 9 +- symfony.lock | 16 + webpack.config.js | 73 ++++ 11 files changed, 658 insertions(+), 258 deletions(-) create mode 100644 assets/app.js create mode 100644 assets/styles/app.css create mode 100644 config/packages/webpack_encore.yaml create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index e11ad8b..57ce12b 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,10 @@ phpstan.neon # Ignore package-lock.json package-lock.json + +###> symfony/webpack-encore-bundle ### +/node_modules/ +/public/build/ +npm-debug.log +yarn-error.log +###< symfony/webpack-encore-bundle ### diff --git a/assets/app.js b/assets/app.js new file mode 100644 index 0000000..d4f56b3 --- /dev/null +++ b/assets/app.js @@ -0,0 +1,104 @@ +import './styles/app.css'; + +document.addEventListener('DOMContentLoaded', () => { + const qrCodeContainer = document.getElementById('qrCodeContainer'); + const tabsContainer = document.getElementById('qrCodeTabs'); // Navigation tabs + const tabContentContainer = document.getElementById('qrCodeTabContent'); // Tab content + const form = document.querySelector('.form-wrapper form'); + const selectedQrCodes = document.getElementById('selectedQrCodes'); + + // Ensure all containers and elements exist + if (!qrCodeContainer || !tabsContainer || !tabContentContainer || !form) { + console.error('Required elements not found!'); + return; + } + + const generateQrPath = qrCodeContainer.dataset.generateQrPath; + + if (!generateQrPath) { + console.error('QR Code generate path is missing! Add the "data-generate-qr-path" attribute.'); + return; + } + + async function updateQRCode() { + // Clear tab and content containers + tabsContainer.innerHTML = ''; + tabContentContainer.innerHTML = ''; + + // Prepare form data for POST request + const formData = new FormData(form); + formData.append('selectedQrCodes', selectedQrCodes.value); + + try { + // Fetch the QR codes from the endpoint + const response = await fetch(generateQrPath, { + method: 'POST', + body: formData, + }); + + if (response.ok) { + const data = await response.json(); + const qrCodes = data.qrCodes; // Array of qr titles and generated base64 images + + if (typeof qrCodes === 'object') { + // Loop through all images and create tabs dynamically + Object.entries(qrCodes).forEach(([title, imageSrc]) => { + // Sanitize the title to create valid IDs + const sanitizedTitle = title.replace(/[^a-zA-Z0-9-_]/g, '_'); + + // Create a unique tab ID + const tabId = `qrCodeTab-${sanitizedTitle}`; + const tabPaneId = `qrCodeContent-${sanitizedTitle}`; + + // Create tab navigation item + const tabItem = document.createElement('li'); + tabItem.className = 'nav-item'; + tabItem.role = 'presentation'; + tabItem.innerHTML = ` + + `; + tabsContainer.appendChild(tabItem); + + // Create tab content (image) + const tabContent = document.createElement('div'); + tabContent.className = `tab-pane fade ${tabsContainer.children.length === 1 ? 'show active' : ''} qr-code-tab-pane`; + tabContent.id = tabPaneId; + tabContent.role = 'tabpanel'; + tabContent.innerHTML = ` + QR Code titled ${title} + `; + tabContentContainer.appendChild(tabContent); + }); + } else { + console.error('Invalid data format. Expected an array of QR code images.'); + } + } else { + console.error('Failed to fetch QR codes. Status:', response.status); + } + } catch (error) { + console.error('Error while fetching QR codes:', error); + } + } + + // Timeout before updating qr code after typing + let typingTimer; + + form.addEventListener('input', () => { + clearTimeout(typingTimer); + + typingTimer = setTimeout(() => { + updateQRCode(); + }, 500); + }); + + updateQRCode(); +}); diff --git a/assets/styles/app.css b/assets/styles/app.css new file mode 100644 index 0000000..ad7b868 --- /dev/null +++ b/assets/styles/app.css @@ -0,0 +1,72 @@ + +.qr-preview h3 { + margin-bottom: 10px; +} + +.form-wrapper { + display: flex; +} + +.form-wrapper form { + flex: 1; + padding-right: 30px; +} + +.popover-link { + position: relative; + display: inline-block; + text-decoration: underline; +} + +.popover-content { + display: none; + position: absolute; + top: 120%; + left: 50%; + transform: translateX(-50%); + background-color: white; + border: 1px solid #ccc; + border-radius: 5px; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + padding: 5px; + z-index: 1000; + white-space: nowrap; +} + +.popover-content img { + max-width: 200px; + max-height: 200px; +} + +.popover-link:hover .popover-content { + display: block; +} + + +.qr-preview { + display: flex; + flex-direction: column; + border: 1px solid #ddd; + border-radius: 6px; + background-color: #f9f9f9; + flex: 1; + height: 475px; + + .nav-link { + color: #000; + } + .nav-link.active { + color: #000; + font-weight: bold; + } +} + +.qr-preview .qr-code-tab-pane { + text-align: center; +} + +.qr-preview .qr-code-image { + max-width: 100%; + display: block; + margin: 15px auto 0 auto; +} diff --git a/composer.json b/composer.json index 3641b28..224ed4a 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "symfony/maker-bundle": "^1.62.1", "symfony/runtime": "~7.2.0", "symfony/twig-bundle": "~7.2.0", + "symfony/webpack-encore-bundle": "^2.2", "symfony/yaml": "~7.2.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index f2e3eb2..8abf02d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f8fd90c612d525dcf4f978cb04ff50c0", + "content-hash": "5e90b0f2dd5de7cebd56c773cf88835a", "packages": [ { "name": "api-platform/core", @@ -2479,257 +2479,6 @@ }, "time": "2024-12-30T11:07:19+00:00" }, - { - "name": "phpstan/phpstan", - "version": "2.1.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "7d08f569e582ade182a375c366cbd896eccadd3a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a", - "reference": "7d08f569e582ade182a375c366cbd896eccadd3a", - "shasum": "" - }, - "require": { - "php": "^7.4|^8.0" - }, - "conflict": { - "phpstan/phpstan-shim": "*" - }, - "bin": [ - "phpstan", - "phpstan.phar" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "keywords": [ - "dev", - "static analysis" - ], - "support": { - "docs": "https://phpstan.org/user-guide/getting-started", - "forum": "https://github.com/phpstan/phpstan/discussions", - "issues": "https://github.com/phpstan/phpstan/issues", - "security": "https://github.com/phpstan/phpstan/security/policy", - "source": "https://github.com/phpstan/phpstan-src" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - } - ], - "time": "2025-01-21T14:54:06+00:00" - }, - { - "name": "phpstan/phpstan-doctrine", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "bdb6a835c5aa9725979694ae9b70591e180f4853" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/bdb6a835c5aa9725979694ae9b70591e180f4853", - "reference": "bdb6a835c5aa9725979694ae9b70591e180f4853", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.0.3" - }, - "conflict": { - "doctrine/collections": "<1.0", - "doctrine/common": "<2.7", - "doctrine/mongodb-odm": "<1.2", - "doctrine/orm": "<2.5", - "doctrine/persistence": "<1.3" - }, - "require-dev": { - "cache/array-adapter": "^1.1", - "composer/semver": "^3.3.2", - "cweagans/composer-patches": "^1.7.3", - "doctrine/annotations": "^2.0", - "doctrine/collections": "^1.6 || ^2.1", - "doctrine/common": "^2.7 || ^3.0", - "doctrine/dbal": "^3.3.8", - "doctrine/lexer": "^2.0 || ^3.0", - "doctrine/mongodb-odm": "^2.4.3", - "doctrine/orm": "^2.16.0", - "doctrine/persistence": "^2.2.1 || ^3.2", - "gedmo/doctrine-extensions": "^3.8", - "nesbot/carbon": "^2.49", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6.20", - "ramsey/uuid": "^4.2", - "symfony/cache": "^5.4" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon", - "rules.neon" - ] - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Doctrine extensions for PHPStan", - "support": { - "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.1" - }, - "time": "2024-12-02T16:48:00+00:00" - }, - { - "name": "phpstan/phpstan-phpunit", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "d09e152f403c843998d7a52b5d87040c937525dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/d09e152f403c843998d7a52b5d87040c937525dd", - "reference": "d09e152f403c843998d7a52b5d87040c937525dd", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.0.4" - }, - "conflict": { - "phpunit/phpunit": "<7.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon", - "rules.neon" - ] - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPUnit extensions and rules for PHPStan", - "support": { - "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.4" - }, - "time": "2025-01-22T13:07:38+00:00" - }, - { - "name": "phpstan/phpstan-symfony", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "65f02c7e585f3c7372e42e14d3d87da034031553" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/65f02c7e585f3c7372e42e14d3d87da034031553", - "reference": "65f02c7e585f3c7372e42e14d3d87da034031553", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.1.2" - }, - "conflict": { - "symfony/framework-bundle": "<3.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", - "psr/container": "1.0 || 1.1.1", - "symfony/config": "^5.4 || ^6.1", - "symfony/console": "^5.4 || ^6.1", - "symfony/dependency-injection": "^5.4 || ^6.1", - "symfony/form": "^5.4 || ^6.1", - "symfony/framework-bundle": "^5.4 || ^6.1", - "symfony/http-foundation": "^5.4 || ^6.1", - "symfony/messenger": "^5.4", - "symfony/polyfill-php80": "^1.24", - "symfony/serializer": "^5.4", - "symfony/service-contracts": "^2.2.0" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon", - "rules.neon" - ] - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Lukáš Unger", - "email": "looky.msc@gmail.com", - "homepage": "https://lookyman.net" - } - ], - "description": "Symfony Framework extensions and rules for PHPStan", - "support": { - "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.2" - }, - "time": "2025-01-21T18:57:07+00:00" - }, { "name": "psr/cache", "version": "3.0.0", @@ -7927,16 +7676,88 @@ "time": "2024-09-25T14:21:43+00:00" }, { - "name": "symfony/yaml", - "version": "v7.2.0", + "name": "symfony/webpack-encore-bundle", + "version": "v2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + "url": "https://github.com/symfony/webpack-encore-bundle.git", + "reference": "e335394b68a775a9b2bd173a8ba4fd2001f3870c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", + "url": "https://api.github.com/repos/symfony/webpack-encore-bundle/zipball/e335394b68a775a9b2bd173a8ba4fd2001f3870c", + "reference": "e335394b68a775a9b2bd173a8ba4fd2001f3870c", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/asset": "^5.4 || ^6.2 || ^7.0", + "symfony/config": "^5.4 || ^6.2 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.2 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.2 || ^7.0", + "symfony/service-contracts": "^1.1.9 || ^2.1.3 || ^3.0" + }, + "require-dev": { + "symfony/framework-bundle": "^5.4 || ^6.2 || ^7.0", + "symfony/http-client": "^5.4 || ^6.2 || ^7.0", + "symfony/phpunit-bridge": "^5.4 || ^6.2 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.2 || ^7.0", + "symfony/web-link": "^5.4 || ^6.2 || ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/webpack-encore", + "name": "symfony/webpack-encore" + } + }, + "autoload": { + "psr-4": { + "Symfony\\WebpackEncoreBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Integration of your Symfony app with Webpack Encore", + "support": { + "issues": "https://github.com/symfony/webpack-encore-bundle/issues", + "source": "https://github.com/symfony/webpack-encore-bundle/tree/v2.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-02T07:27:19+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", "reference": "099581e99f557e9f16b43c5916c26380b54abb22", "shasum": "" }, @@ -9759,6 +9580,64 @@ }, "time": "2024-09-04T20:21:43+00:00" }, + { + "name": "phpstan/phpstan", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a", + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-01-21T14:54:06+00:00" + }, { "name": "phpstan/phpstan-deprecation-rules", "version": "2.0.1", @@ -9806,6 +9685,199 @@ }, "time": "2024-11-28T21:56:36+00:00" }, + { + "name": "phpstan/phpstan-doctrine", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-doctrine.git", + "reference": "bdb6a835c5aa9725979694ae9b70591e180f4853" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/bdb6a835c5aa9725979694ae9b70591e180f4853", + "reference": "bdb6a835c5aa9725979694ae9b70591e180f4853", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0.3" + }, + "conflict": { + "doctrine/collections": "<1.0", + "doctrine/common": "<2.7", + "doctrine/mongodb-odm": "<1.2", + "doctrine/orm": "<2.5", + "doctrine/persistence": "<1.3" + }, + "require-dev": { + "cache/array-adapter": "^1.1", + "composer/semver": "^3.3.2", + "cweagans/composer-patches": "^1.7.3", + "doctrine/annotations": "^2.0", + "doctrine/collections": "^1.6 || ^2.1", + "doctrine/common": "^2.7 || ^3.0", + "doctrine/dbal": "^3.3.8", + "doctrine/lexer": "^2.0 || ^3.0", + "doctrine/mongodb-odm": "^2.4.3", + "doctrine/orm": "^2.16.0", + "doctrine/persistence": "^2.2.1 || ^3.2", + "gedmo/doctrine-extensions": "^3.8", + "nesbot/carbon": "^2.49", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6.20", + "ramsey/uuid": "^4.2", + "symfony/cache": "^5.4" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Doctrine extensions for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-doctrine/issues", + "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.1" + }, + "time": "2024-12-02T16:48:00+00:00" + }, + { + "name": "phpstan/phpstan-phpunit", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-phpunit.git", + "reference": "d09e152f403c843998d7a52b5d87040c937525dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/d09e152f403c843998d7a52b5d87040c937525dd", + "reference": "d09e152f403c843998d7a52b5d87040c937525dd", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0.4" + }, + "conflict": { + "phpunit/phpunit": "<7.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPUnit extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-phpunit/issues", + "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.4" + }, + "time": "2025-01-22T13:07:38+00:00" + }, + { + "name": "phpstan/phpstan-symfony", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-symfony.git", + "reference": "65f02c7e585f3c7372e42e14d3d87da034031553" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/65f02c7e585f3c7372e42e14d3d87da034031553", + "reference": "65f02c7e585f3c7372e42e14d3d87da034031553", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.2" + }, + "conflict": { + "symfony/framework-bundle": "<3.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "psr/container": "1.0 || 1.1.1", + "symfony/config": "^5.4 || ^6.1", + "symfony/console": "^5.4 || ^6.1", + "symfony/dependency-injection": "^5.4 || ^6.1", + "symfony/form": "^5.4 || ^6.1", + "symfony/framework-bundle": "^5.4 || ^6.1", + "symfony/http-foundation": "^5.4 || ^6.1", + "symfony/messenger": "^5.4", + "symfony/polyfill-php80": "^1.24", + "symfony/serializer": "^5.4", + "symfony/service-contracts": "^2.2.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukáš Unger", + "email": "looky.msc@gmail.com", + "homepage": "https://lookyman.net" + } + ], + "description": "Symfony Framework extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-symfony/issues", + "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.2" + }, + "time": "2025-01-21T18:57:07+00:00" + }, { "name": "react/cache", "version": "v1.2.0", diff --git a/config/bundles.php b/config/bundles.php index 925c7d6..2fc7a87 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -15,4 +15,5 @@ Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], ItkDev\OpenIdConnectBundle\ItkDevOpenIdConnectBundle::class => ['all' => true], + Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], ]; diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 7e1ee1f..76fd3e1 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -5,6 +5,8 @@ framework: # Note that the session will be started ONLY if you read or write from it. session: true + trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix'] + trusted_proxies: '127.0.0.1,REMOTE_ADDR' #esi: true #fragments: true diff --git a/config/packages/webpack_encore.yaml b/config/packages/webpack_encore.yaml new file mode 100644 index 0000000..4c009ee --- /dev/null +++ b/config/packages/webpack_encore.yaml @@ -0,0 +1,45 @@ +webpack_encore: + # The path where Encore is building the assets - i.e. Encore.setOutputPath() + output_path: '%kernel.project_dir%/public/build' + # If multiple builds are defined (as shown below), you can disable the default build: + # output_path: false + + # Set attributes that will be rendered on all script and link tags + script_attributes: + defer: true + # Uncomment (also under link_attributes) if using Turbo Drive + # https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change + # 'data-turbo-track': reload + # link_attributes: + # Uncomment if using Turbo Drive + # 'data-turbo-track': reload + + # If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials') + # crossorigin: 'anonymous' + + # Preload all rendered script and link tags automatically via the HTTP/2 Link header + # preload: true + + # Throw an exception if the entrypoints.json file is missing or an entry is missing from the data + # strict_mode: false + + # If you have multiple builds: + # builds: + # frontend: '%kernel.project_dir%/public/frontend/build' + + # pass the build name as the 3rd argument to the Twig functions + # {{ encore_entry_script_tags('entry1', null, 'frontend') }} + +framework: + assets: + json_manifest_path: '%kernel.project_dir%/public/build/manifest.json' + +#when@prod: +# webpack_encore: +# # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes) +# # Available in version 1.2 +# cache: true + +#when@test: +# webpack_encore: +# strict_mode: false diff --git a/package.json b/package.json index 2a82596..cf6589c 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,16 @@ "private": true, "description": "Tooling setup for linting", "devDependencies": { - "markdownlint-cli": "^0.35.0" + "@symfony/webpack-encore": "^5.1.0", + "core-js": "^3.40.0", + "markdownlint-cli": "^0.35.0", + "webpack-notifier": "^1.15.0" }, "scripts": { + "dev-server": "encore dev-server", + "dev": "encore dev", + "watch": "encore dev --watch", + "build": "encore production --progress", "coding-standards-check/markdownlint": "markdownlint --ignore 'node_modules' --ignore 'vendor' README.md CHANGELOG.md 'docs/**/*.md'", "coding-standards-check": "yarn coding-standards-check/markdownlint", "coding-standards-apply/markdownlint": "markdownlint --fix README.md CHANGELOG.md docs/*.md docs/**/*.md", diff --git a/symfony.lock b/symfony.lock index 328914f..be9c91e 100644 --- a/symfony.lock +++ b/symfony.lock @@ -254,6 +254,22 @@ "config/routes/web_profiler.yaml" ] }, + "symfony/webpack-encore-bundle": { + "version": "2.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.0", + "ref": "35ee1edee91a1a7137095f53db7ed0c20884b745" + }, + "files": [ + "assets/app.js", + "assets/styles/app.css", + "config/packages/webpack_encore.yaml", + "package.json", + "webpack.config.js" + ] + }, "twig/extra-bundle": { "version": "v3.18.0" }, diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..97de62c --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,73 @@ +const Encore = require('@symfony/webpack-encore'); + +// Manually configure the runtime environment if not already configured yet by the "encore" command. +// It's useful when you use tools that rely on webpack.config.js file. +if (!Encore.isRuntimeEnvironmentConfigured()) { + Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); +} + +Encore + // directory where compiled assets will be stored + .setOutputPath('public/build/') + // public path used by the web server to access the output path + .setPublicPath('/build') + // only needed for CDN's or subdirectory deploy + //.setManifestKeyPrefix('build/') + + /* + * ENTRY CONFIG + * + * Each entry will result in one JavaScript file (e.g. app.js) + * and one CSS file (e.g. app.css) if your JavaScript imports CSS. + */ + .addEntry('app', './assets/app.js') + + // When enabled, Webpack "splits" your files into smaller pieces for greater optimization. + .splitEntryChunks() + + // will require an extra script tag for runtime.js + // but, you probably want this, unless you're building a single-page app + .enableSingleRuntimeChunk() + + /* + * FEATURE CONFIG + * + * Enable & configure other features below. For a full + * list of features, see: + * https://symfony.com/doc/current/frontend.html#adding-more-features + */ + .cleanupOutputBeforeBuild() + .enableBuildNotifications() + .enableSourceMaps(!Encore.isProduction()) + // enables hashed filenames (e.g. app.abc123.css) + .enableVersioning(Encore.isProduction()) + + // configure Babel + // .configureBabel((config) => { + // config.plugins.push('@babel/a-babel-plugin'); + // }) + + // enables and configure @babel/preset-env polyfills + .configureBabelPresetEnv((config) => { + config.useBuiltIns = 'usage'; + config.corejs = '3.38'; + }) + + // enables Sass/SCSS support + //.enableSassLoader() + + // uncomment if you use TypeScript + //.enableTypeScriptLoader() + + // uncomment if you use React + //.enableReactPreset() + + // uncomment to get integrity="..." attributes on your script & link tags + // requires WebpackEncoreBundle 1.4 or higher + //.enableIntegrityHashes(Encore.isProduction()) + + // uncomment if you're having problems with a jQuery plugin + //.autoProvidejQuery() +; + +module.exports = Encore.getWebpackConfig(); From bbcbf969940789f3efc7e492138563eaed5d5d30 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:39:07 +0100 Subject: [PATCH 05/14] Passing selected qr codes to qr code previewer --- src/Controller/BatchDownloadController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controller/BatchDownloadController.php b/src/Controller/BatchDownloadController.php index 92ef699..57d70e8 100644 --- a/src/Controller/BatchDownloadController.php +++ b/src/Controller/BatchDownloadController.php @@ -46,6 +46,7 @@ public function index(): Response return $this->render('form/batchDownload.html.twig', [ 'form' => $form, + 'selectedQrCodes' => json_encode($request->query->all()), 'count' => count($request->query->all()), ]); } From 6b515c1e772d0774e8c91bfe0f71ed3639852f11 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:40:48 +0100 Subject: [PATCH 06/14] Changed base twig to newly modified base --- templates/form/setUrl.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/form/setUrl.html.twig b/templates/form/setUrl.html.twig index 449840b..56e95a1 100644 --- a/templates/form/setUrl.html.twig +++ b/templates/form/setUrl.html.twig @@ -1,4 +1,4 @@ -{% extends '@EasyAdmin/page/content.html.twig' %} +{% extends 'EasyAdminBundle/content.html.twig' %} {% form_theme form '@EasyAdmin/crud/form_theme.html.twig' %} {% block main %} From 1e26d2f6a3b62cf6165b4ee878581a76135129e7 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:40:55 +0100 Subject: [PATCH 07/14] moved inline styling --- templates/fields/link/link.html.twig | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/templates/fields/link/link.html.twig b/templates/fields/link/link.html.twig index e0c594f..bdf671e 100644 --- a/templates/fields/link/link.html.twig +++ b/templates/fields/link/link.html.twig @@ -8,33 +8,5 @@ From da3739f1befdacf64ddb41e4950bdb8cc4c97961 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:42:02 +0100 Subject: [PATCH 08/14] Using passed selected qr codes to return an array of qr codes --- src/Controller/QrCodePreviewController.php | 78 ++++++++++++++-------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/src/Controller/QrCodePreviewController.php b/src/Controller/QrCodePreviewController.php index 40ac8c2..bed914e 100644 --- a/src/Controller/QrCodePreviewController.php +++ b/src/Controller/QrCodePreviewController.php @@ -3,6 +3,7 @@ namespace App\Controller; use App\Helper\DownloadHelper; +use App\Repository\QrRepository; use Endroid\QrCode\Builder\Builder; use Endroid\QrCode\Encoding\Encoding; use Endroid\QrCode\ErrorCorrectionLevel; @@ -18,26 +19,29 @@ { public function __construct( private DownloadHelper $downloadHelper, + private readonly QrRepository $qrRepository, ) { } /** - * Handles the generation of a QR codes for review before batch download. - * Provides the QR code as a base64-encoded PNG in the response. + * Handles the generation of QR codes for multiple selected entities. + * Returns the QR codes as base64-encoded strings in an array. * - * @param Request $request the HTTP request containing parameters for the QR code + * @param Request $request the HTTP request containing parameters for the QR codes * - * @return JsonResponse a JSON response containing the generated QR code as a base64-encoded string + * @return JsonResponse a JSON response containing the generated QR codes as a base64-encoded array * * @throws ValidationException */ - #[Route('/generate-qr-code', name: 'generate_qr_code', methods: ['POST'])] + #[Route('/generate-qr-codes', name: 'generate_qr_codes', methods: ['POST'])] public function generateQrCode(Request $request): JsonResponse { // Extract data from the request $data = $request->request->all(); $downloadSettings = $data['batch_download'] ?? []; + $selectedQrCodes = $data['selectedQrCodes'] ?? []; + $selectedQrCodes = json_decode($selectedQrCodes, true); $logo = $request->files->get('batch_download')['logo'] ?? null; @@ -45,8 +49,12 @@ public function generateQrCode(Request $request): JsonResponse $logo = null; } - // Build the data you want encoded in the QR code - $qrString = 'https://www.google.dk'; + // Validate selected QR codes + if (!is_array($selectedQrCodes) || empty($selectedQrCodes)) { + return new JsonResponse([ + 'error' => 'No QR codes selected.', + ], 400); + } // Get QR code settings or use defaults $size = (int) min(400, $downloadSettings['size'] ?? 400); @@ -66,30 +74,44 @@ public function generateQrCode(Request $request): JsonResponse 'high' => ErrorCorrectionLevel::High, ][$downloadSettings['errorCorrectionLevel'] ?? 'medium'] ?? ErrorCorrectionLevel::Medium; - // Generate the QR Code using Endroid QR Code Builder - $builder = new Builder(); - $result = $builder->build( - data: $qrString, - encoding: new Encoding('UTF-8'), - errorCorrectionLevel: $errorCorrectionLevel, - size: $size, - margin: $margin, - foregroundColor: $foregroundColor, - backgroundColor: $backgroundColor, - labelText: $labelText, - labelAlignment: LabelAlignment::Center, - labelMargin: $labelMargin, - labelTextColor: $labelTextColor, - logoPath: $logo, - logoPunchoutBackground: false, - ); + // Initialize the array for storing base64-encoded QR codes + $data = []; + + // Loop through each selected QR code entity ID + foreach ($selectedQrCodes as $qrCodeId) { + // Replace this with logic to retrieve the URL (or string) for each QR code entity + $qrCodeUrl = $this->qrRepository->findOneBy(['id' => $qrCodeId])->getUrls()->first()->getUrl(); + $qrCodeTitle = $this->qrRepository->findOneBy(['id' => $qrCodeId])->getTitle(); + + if (!$qrCodeUrl) { + continue; + } - // Convert the QR code image to base64 - $qrCodeBase64 = base64_encode($result->getString()); + // Generate the QR Code using Endroid QR Code Builder + $builder = new Builder(); + $result = $builder->build( + data: $qrCodeUrl, + encoding: new Encoding('UTF-8'), + errorCorrectionLevel: $errorCorrectionLevel, + size: $size, + margin: $margin, + foregroundColor: $foregroundColor, + backgroundColor: $backgroundColor, + labelText: $labelText, + labelAlignment: LabelAlignment::Center, + labelMargin: $labelMargin, + labelTextColor: $labelTextColor, + logoPath: $logo, + logoPunchoutBackground: false, + ); + + // Convert the QR code image to base64 and add to the array + $data[$qrCodeTitle] = 'data:image/png;base64,' . base64_encode($result->getString()); + } - // Respond with the QR code as a base64-encoded PNG + // Respond with the array of QR codes as base64-encoded PNGs return new JsonResponse([ - 'qrCode' => 'data:image/png;base64,'.$qrCodeBase64, + 'qrCodes' => $data, ]); } } From 496993f83f889148192cc9b5c8fb40ab98c2aca9 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:42:36 +0100 Subject: [PATCH 09/14] Modified preview twig to contain dynamically generated images returned from javascript --- templates/form/batchDownload.html.twig | 92 +++----------------------- 1 file changed, 11 insertions(+), 81 deletions(-) diff --git a/templates/form/batchDownload.html.twig b/templates/form/batchDownload.html.twig index 2e34b50..a11ece1 100644 --- a/templates/form/batchDownload.html.twig +++ b/templates/form/batchDownload.html.twig @@ -1,8 +1,10 @@ -{% extends '@EasyAdmin/page/content.html.twig' %} +{% extends 'EasyAdminBundle/content.html.twig' %} {% form_theme form '@EasyAdmin/crud/form_theme.html.twig' %} {% block main %} + - - - - {% endblock %} From d85f654c20042b6e45c240611c8e193260eff89f Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:45:42 +0100 Subject: [PATCH 10/14] Coding standards --- src/Controller/QrCodePreviewController.php | 2 +- src/DataFixtures/AppFixtures.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Controller/QrCodePreviewController.php b/src/Controller/QrCodePreviewController.php index bed914e..c39d864 100644 --- a/src/Controller/QrCodePreviewController.php +++ b/src/Controller/QrCodePreviewController.php @@ -106,7 +106,7 @@ public function generateQrCode(Request $request): JsonResponse ); // Convert the QR code image to base64 and add to the array - $data[$qrCodeTitle] = 'data:image/png;base64,' . base64_encode($result->getString()); + $data[$qrCodeTitle] = 'data:image/png;base64,'.base64_encode($result->getString()); } // Respond with the array of QR codes as base64-encoded PNGs diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index abbe8d3..d77837d 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -31,7 +31,7 @@ public function load(ObjectManager $manager): void // Create Qr entities for ($i = 0; $i < 80; ++$i) { $qr = new Qr(); - $qr->setTitle('qr ' . $i); + $qr->setTitle('qr '.$i); $qr->setDepartment(0 == $i % 2 ? $departments[0] : $departments[1]); $qr->setAuthor('fixture_author'); $qr->setMode(QrModeEnum::DEFAULT); @@ -44,7 +44,7 @@ public function load(ObjectManager $manager): void $manager->persist($qr); $url = new Url(); - $url->setUrl('http://localhost/loremipsum/long_url/' . $i); + $url->setUrl('http://localhost/loremipsum/long_url/'.$i); $url->setQr($qr); $url->setTenant($tenant); $url->setCreatedAt(new \DateTimeImmutable()); From 6c917ebf273b302c361bdb9e9364a77da232aac3 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:46:36 +0100 Subject: [PATCH 11/14] Updated changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44d9d88..3af2928 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ See [keep a changelog] for information about writing changes to this log. ## [Unreleased] +[PR-18](https://github.com/itk-dev/itqr/pull/18) + - Extract inline assets + - Improve download preview to serve multiple reviews [PR-17](https://github.com/itk-dev/itqr/pull/17) - Cleanup github actions, Standardize on using docker compose [PR-14](https://github.com/itk-dev/itqr/pull/14) From fb25b3b4e2f6199f26fa2f538d590b88242f3793 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:50:14 +0100 Subject: [PATCH 12/14] Added composer audit GA check --- .github/workflows/pr.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index b0f6beb..89dfba7 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -113,3 +113,12 @@ jobs: docker compose run --rm phpfpm composer install docker compose run --rm phpfpm bin/console api:openapi:export --yaml --output=public/spec.yaml --no-interaction git diff --diff-filter=ACMRT --exit-code public/spec.yaml + + composer-audit: + name: Run composer audit + runs-on: ubuntu-latest + steps: + - run: | + docker network create frontend + docker compose run --rm phpfpm composer install + docker compose run --rm phpfpm composer audit From 1c9d0a570eb7375637cd4788bfd7b180af142054 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:51:12 +0100 Subject: [PATCH 13/14] ga check --- .github/workflows/pr.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 89dfba7..20f5a4e 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -118,6 +118,7 @@ jobs: name: Run composer audit runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - run: | docker network create frontend docker compose run --rm phpfpm composer install From faffba55f8ccf4c1247adaa46403463022c00971 Mon Sep 17 00:00:00 2001 From: Jeppe Krogh Date: Fri, 21 Feb 2025 14:54:39 +0100 Subject: [PATCH 14/14] Security updates --- composer.json | 3 ++- composer.lock | 19 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 224ed4a..ff8c586 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "symfony/runtime": "~7.2.0", "symfony/twig-bundle": "~7.2.0", "symfony/webpack-encore-bundle": "^2.2", - "symfony/yaml": "~7.2.0" + "symfony/yaml": "~7.2.0", + "twig/twig": "^3.19.0" }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^4.0", diff --git a/composer.lock b/composer.lock index 8abf02d..80f574b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5e90b0f2dd5de7cebd56c773cf88835a", + "content-hash": "1b22cfc314c25b2ccde305256618d71b", "packages": [ { "name": "api-platform/core", @@ -7963,24 +7963,23 @@ }, { "name": "twig/twig", - "version": "v3.18.0", + "version": "v3.20.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50" + "reference": "3468920399451a384bef53cf7996965f7cd40183" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50", - "reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3468920399451a384bef53cf7996965f7cd40183", + "reference": "3468920399451a384bef53cf7996965f7cd40183", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php81": "^1.29" + "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "phpstan/phpstan": "^2.0", @@ -8027,7 +8026,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.18.0" + "source": "https://github.com/twigphp/Twig/tree/v3.20.0" }, "funding": [ { @@ -8039,7 +8038,7 @@ "type": "tidelift" } ], - "time": "2024-12-29T10:51:50+00:00" + "time": "2025-02-13T08:34:43+00:00" }, { "name": "willdurand/negotiation",