Search by

nowo-tech / qr-code-bundle

HecFranco

Symfony bundle to generate PNG QR codes as data URIs with optional URL safety policy.

Package info

github.com/nowo-tech/QrCodeBundle

Type:symfony-bundle

pkg:composer/nowo-tech/qr-code-bundle

Fund package maintenance!

HecFranco

Statistics

Installs: 1 373

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.12.0 2026-11-11 02:06 UTC

README

CI Packagist Version Packagist Downloads License PHP Symfony GitHub stars Coverage

⭐ Found this useful? Install from Packagist · Give it a star on GitHub so more developers can find it.

Symfony bundle to generate PNG QR codes as data URIs, with optional URL validation (http/https only) and host allowlisting.

Used by WalletQrBundle for wallet save-link QRs, and usable standalone in any Symfony app.

FrankenPHP Friendly Worker Mode

This bundle is FrankenPHP worker mode friendly.

It supports workers that do not reset the Symfony kernel between requests. YAML-only setups are fully stateless; with use_database_config: true, profiles are read without the Doctrine identity map and closed EntityManagers are recovered (see docs/FRANKENPHP-WORKER-AUDIT.md).

QR codes (Twig functions, Twig component, QrCodeService) Database profiles admin (UiKit list) Profile form (UiKit form + delete zone)
QR codes rendered by the Twig functions, the NowoQrCode Twig component and QrCodeService with the default and compact profiles Admin list of the database QR profiles: YAML overrides and database-only profiles with size, margin, error correction and URL allowlist Edit form of the wallet-pass QR profile with the danger zone

Features

  • ✅ PNG QR codes as data URIs (QrCodeService / QrCodeDataUriRenderer)
  • ✅ Named profiles (default_profile + profiles) for size, ECC, and allowlists
  • ✅ Optional Doctrine storage: DB profiles override YAML by name (use_database_config)
  • ✅ Admin CRUD at /admin/qr-code-profiles (when DB storage is enabled; requires FormKit + UiKit)
  • ✅ Panel security: security.access_roles (default [ROLE_ADMIN]) / allow_unauthenticated (see CONFIGURATION)
  • ✅ URL safety policy (QrUrlPolicy; blocks javascript:, data:, etc.)
  • ✅ Optional host/URL allowlist (exact host or subdomain; host/path prefixes; #regex)
  • ✅ Typed QrErrorCorrection enum (low | medium | quartile | high)
  • ✅ Twig helpers qr_code_data_uri and qr_code_for_url (optional profile argument)
  • ✅ Twig UX component <twig:NowoQrCode> (symfony/ux-twig-component)
  • ✅ Compatible with Symfony UX Toolkit (optional host dependency, PHP 8.4+)
  • ✅ Symfony configuration under nowo_qr_code

Quick start

composer require nowo-tech/qr-code-bundle

Requires PHP gd (or another writer backend supported by endroid/qr-code).

# config/packages/nowo_qr_code.yaml
nowo_qr_code:
    default_profile: default
    profiles:
        default:
            size: 300
            margin: 10
            error_correction: high
            url_allowlist: []
        compact:
            size: 128
            margin: 2
            error_correction: medium
            url_allowlist:
                - example.com
use Nowo\QrCodeBundle\Service\QrCodeService;

$dataUri = $qrCodeService->createDataUri('https://example.com');
$safeUri = $qrCodeService->createDataUriForUrl('https://example.com/path', 'compact');
<img src="{{ qr_code_data_uri('Hello') }}" alt="QR">
<img src="{{ qr_code_for_url(downloadUrl, 'compact') }}" alt="QR">
<twig:NowoQrCode content="Hello" class="qr" />
<twig:NowoQrCode url="{{ downloadUrl }}" profile="compact" />

Related

  • WalletQrBundle — Google Wallet / Apple Wallet save links + QR (depends on this bundle)

Demo (FrankenPHP)

make -C demo/symfony8 up
# http://localhost:8012/demo
# http://localhost:8012/admin/qr-code-profiles (dev: database profiles on SQLite, seeded)

See docs/DEMO-FRANKENPHP.md (FRANKENPHP_MODE=worker default; PHP 8.5 + gd).

The screenshots at the top come from this demo. Refresh them with make -C demo/symfony8 demo-screenshots; make -C demo/symfony8 test-e2e runs the Playwright happy paths (QR rendering and the profile admin: list, create, edit, delete through the confirm dialog, YAML import).

Documentation

Additional documentation

Tests and coverage

Stack Coverage How to run
PHP 100% lines (src/) make test-coverage / composer test-coverage
TypeScript / JavaScript N/A (no frontend assets) —
Python N/A —

CI enforces PHP coverage at 100% (Clover elements / line gate via .scripts/coverage-check-100.php).

License

MIT © Nowo.tech