qr_generator-1.0.1/src/Form/QRCodeExportForm.php

src/Form/QRCodeExportForm.php
<?php

declare(strict_types=1);

namespace Drupal\qr_generator\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Endroid\QrCode\Builder\Builder;
use Symfony\Component\HttpFoundation\Response;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\Writer\SvgWriter;
use Endroid\QrCode\Writer\PdfWriter;

/**
 * Form controller for generating and exporting QR codes.
 *
 * This form allows users to create a QR code for a given entity
 * and download it in one of several output formats (PNG, SVG, PDF).
 * The QR code content is based on an internal URL generated from
 * the UUID of the target `qr_code` entity passed in the route.
 *
 * Features:
 * - Configurable QR code size (in pixels) and margin.
 * - Output format selection with built-in validation.
 * - Uses the Endroid\QrCode library to generate images.
 * - Streams the generated QR code directly to the browser as a file download.
 *
 * Workflow:
 * 1. User enters size, margin, and selects output format.
 * 2. On submit, the form constructs an absolute URL for the entity.
 * 3. The appropriate writer (PNG, SVG, or PDF) is instantiated.
 * 4. The QR code is built with the Endroid\QrCode\Builder API.
 * 5. The binary result is returned as an HTTP response with appropriate
 *    content type and download filename.
 *
 * @package Drupal\qr_generator\Form
 */
final class QRCodeExportForm extends FormBase
{

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string
  {
    return 'qr_generator_q_r_code_export';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array
  {

    $form['size'] = [
      '#type' => 'number',
      '#title' => $this->t('Size (px)'),
      '#default_value' => 300,
      '#min' => 100,
      '#max' => 1000,
    ];
    $form['margin'] = [
      '#type' => 'number',
      '#title' => $this->t('Margin'),
      '#default_value' => 10,
      '#min' => 0,
      '#max' => 50,
    ];

    $form['format'] = [
      '#type' => 'select',
      '#title' => $this->t('Output format'),
      '#options' => [
        'png' => 'PNG',
        'svg' => 'SVG',
        'pdf' => 'PDF',
      ],
      '#default_value' => 'png',
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Generate QR Code'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void
  {
    $size = (int) $form_state->getValue('size');
    $margin = (int) $form_state->getValue('margin');
    $format = $form_state->getValue('format');

    // Validate size
    if ($size <= 0) {
      $form_state->setErrorByName('size', $this->t('Size must be a positive number.'));
    }

    // Validate margin
    if ($margin < 0) {
      $form_state->setErrorByName('margin', $this->t('Margin cannot be negative.'));
    }

    // Validate format
    $allowed_formats = ['png', 'pdf', 'svg']; // Example allowed values
    if (!in_array($format, $allowed_formats)) {
      $form_state->setErrorByName('format', $this->t('Invalid format selected. Allowed formats: @formats', [
        '@formats' => implode(', ', $allowed_formats),
      ]));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void
  {
    $size = (int) $form_state->getValue('size');
    $margin = (int) $form_state->getValue('margin');
    $format = $form_state->getValue('format');
    $entity = \Drupal::routeMatch()->getParameter('qr_code');
    $url = Url::fromUri('internal:/api/qr-code/' . $entity->uuid())->setAbsolute()->toString();

    // Determine writer
    $writer = match ($format) {
      'svg' => new SvgWriter(),
      'pdf' => new PdfWriter(),
      default => new PngWriter(),
    };
    
    $builder = new Builder();
    $result = $builder->build($writer, null, false, $url, null, null, $size, $margin);
    $filename = $entity->uuid() . '_' . \Drupal::time()->getCurrentTime() . '.' . $format;
    $response = new Response($result->getString());
    $response->headers->set('Content-Type', $result->getMimeType());
    $response->headers->set('Content-Disposition', 'attachment; filename="'.$filename.'"');
    $response->send();
    exit;
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc