qr_generator-1.0.1/src/Plugin/rest/resource/QRRestResource.php

src/Plugin/rest/resource/QRRestResource.php
<?php

declare(strict_types=1);

namespace Drupal\qr_generator\Plugin\rest\resource;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\qr_generator\Exception\QRCodeExpiredHttpException;
use Drupal\rest\Attribute\RestResource;
use Drupal\rest\Plugin\ResourceBase;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * REST resource for retrieving and redirecting QR code entities by UUID.
 *
 * This REST plugin exposes a read-only GET endpoint at
 * `/api/qr-code/{uuid}` which:
 *   - Validates that a `qr_code` entity with the provided UUID exists.
 *   - Checks whether the QR code has expired based on its `field_expires` value.
 *   - Redirects the client to the target URL stored in `field_redirect_url`.
 *
 * If the entity does not exist, a 404 Not Found response is returned.
 * If the QR code has expired, a `QRCodeExpiredHttpException` is thrown.
 * Otherwise, the client receives a `TrustedRedirectResponse` to the target URL.
 *
 * Typical use cases:
 * - Serving as the scan target for generated QR codes, enabling them to
 *   redirect users to their intended destination.
 * - Providing a centralized place to enforce expiry rules and manage
 *   redirection logic for QR code entities.
 *
 * Route & HTTP method:
 * - GET /api/qr-code/{uuid}
 *
 * Access control:
 * - Currently allows all requests without authentication or permission checks.
 *   Adjust the `access()` method if additional security is required.
 *
 * @package Drupal\qr_generator\Plugin\rest\resource
 *
 * @see \Drupal\rest\Plugin\rest\resource\EntityResource
 * @see \Drupal\rest\Plugin\ResourceBase
 */
#[RestResource(
  id: 'qr_code_rest_resource',
  label: new TranslatableMarkup('QR Code Rest Resource'),
  uri_paths: [
    'canonical' => '/api/qr-code/{uuid}'
  ],
)]
final class QRRestResource extends ResourceBase
{

  /**
   * The key-value storage.
   */
  private readonly KeyValueStoreInterface $storage;

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    array $serializer_formats,
    LoggerInterface $logger,
    KeyValueFactoryInterface $keyValueFactory,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
    $this->storage = $keyValueFactory->get('qr_generator_rest_resource');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self
  {
    return new self(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->getParameter('serializer.formats'),
      $container->get('logger.factory')->get('rest'),
      $container->get('keyvalue')
    );
  }

  /**
   * Responds to GET requests.
   */
  public function get($uuid): TrustedRedirectResponse
  {
    // Check if entity exist
    $entities = \Drupal::entityTypeManager()->getStorage('qr_code')->loadByProperties(['uuid' => $uuid]);
    if (!$entities) {
      throw new NotFoundHttpException('QR-Code not found!');
    }
    $entity = reset($entities);
    $expired = $entity->get('field_expires')->getString();

    // Check if qr-code expired
    if ($expired) {
      $timestamp = \Drupal::time()->getCurrentTime(); // website datetime in timestamp
      if (!empty($timestamp)) {
        if ($timestamp >= (int)$entity->get('field_expires')->getString()) {
          throw new QRCodeExpiredHttpException('This QR code has expired!');
        }
      }
    }
    return new TrustedRedirectResponse($entity->get('field_redirect_url')->getString());
  }

  public function permissions()
  {
    // Don't declare any permissions, or return empty array
    return [];
  }

  public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE)
  {
    return AccessResult::allowed();
  }
}

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

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