Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 81
QrCodeGenerator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
702.00
0.00% covered (danger)
0.00%
0 / 81
 __construct
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 25
 getErrorCorrectionLevel
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 13
 hexToRgb
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 generateQRCode
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getQRCodeDataUri
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 outputQRCode
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 4
<?php
namespace com\linways\core\ams\professional\service;
use com\linways\core\ams\professional\exception\ProfessionalException;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\ErrorCorrectionLevel;
class QrCodeGenerator extends BaseService
{
    private $content;
    private $size;
    private $margin;
    private $errorCorrectionLevel;
    private $color;
    /**
     * Constructor for QrCodeGenerator.
     *
     * @param string $content The content to encode in the QR code. Defaults to "No Data".
     * @param int $size The size of the QR code. Defaults to 100.
     * @param int|null $margin The margin around the QR code. Defaults to 1/10th of the size.
     * @param string $ec_level The error correction level. One of 'L', 'M', 'Q', 'H'. Defaults to 'H'.
     * @param string $color The color of the QR code in hexadecimal. Defaults to '000000' (black).
     * @throws ProfessionalException if any of the parameters are invalid.
     */
    public function __construct($content = "No Data", $size = 100, $margin = null, $ec_level = 'H', $color = '000000')
    {
        // Validate content
        if (!is_string($content)) {
            throw new ProfessionalException("Content must be a string.");
        }
        $this->content = $content ? $content : "No Data";
        // Validate size
        if (!is_int($size) || $size <= 0) {
            throw new ProfessionalException("Size must be an integer greater than 0.");
        }
        $this->size = $size ? $size : 100;
        // Validate margin
        if ($margin !== null && (!is_int($margin) || $margin < 0)) {
            throw new ProfessionalException("Margin must be null or an integer greater than or equal to 0.");
        }
        $this->margin = ($margin !== null) ? $margin : ceil($this->size / 10);
        // Validate error correction level
        $ec_level= ($ec_level !== null) ? $ec_level : 'H';
        $valid_ec_levels = ['L', 'M', 'Q', 'H'];
        if (!in_array(strtoupper($ec_level), $valid_ec_levels)) {
            throw new ProfessionalException("Error correction level must be one of 'L', 'M', 'Q', 'H'.");
        }
        $this->errorCorrectionLevel = strtoupper($ec_level);
        // Validate color
        $color = ($color !== null) ? $color : '000000';
        if (!preg_match('/^[0-9A-Fa-f]{6}$/', $color)) {
            throw new ProfessionalException("Color must be a valid hexadecimal color code.");
        }
        $this->color = $color;
    }
    /**
     * Gets the error correction level for the QR code.
     *
     * @return ErrorCorrectionLevel The corresponding error correction level object.
     */
    private function getErrorCorrectionLevel()
    {
        switch ($this->errorCorrectionLevel) {
            case 'L':
                return ErrorCorrectionLevel::LOW();
            case 'M':
                return ErrorCorrectionLevel::MEDIUM();
            case 'Q':
                return ErrorCorrectionLevel::QUARTILE();
            case 'H':
            default:
                return ErrorCorrectionLevel::HIGH();
        }
    }
    /**
     * Converts a hexadecimal color string to an RGB array.
     *
     * @param string $hexColor The hexadecimal color string.
     * @return array An associative array with keys 'r', 'g', and 'b'.
     */
    private function hexToRgb($hexColor)
    {
        $hexColor = ltrim($hexColor, '#');
        if (strlen($hexColor) == 3) {
            $hexColor = str_repeat(substr($hexColor, 0, 1), 2) .
                str_repeat(substr($hexColor, 1, 1), 2) .
                str_repeat(substr($hexColor, 2, 1), 2);
        }
        return [
            'r' => hexdec(substr($hexColor, 0, 2)),
            'g' => hexdec(substr($hexColor, 2, 2)),
            'b' => hexdec(substr($hexColor, 4, 2))
        ];
    }
    /**
     * Generates the QR code and returns it as a string.
     *
     * @return string The generated QR code as a string.
     * @throws ProfessionalException If an error occurs during QR code generation.
     */
    public function generateQRCode()
    {
        try {
            $qrCode = new QrCode($this->content);
            $qrCode->setSize($this->size);
            $qrCode->setMargin($this->margin);
            $qrCode->setErrorCorrectionLevel($this->getErrorCorrectionLevel());
            $rgbColor = $this->hexToRgb($this->color);
            $qrCode->setForegroundColor($rgbColor);
            return $qrCode->writeString();
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Generates the QR code and returns it as a data URI.
     *
     * @return string The generated QR code as a data URI.
     * @throws ProfessionalException If an error occurs during QR code generation.
     */
    public function getQRCodeDataUri()
    {
        try {
            $qrCode = new QrCode($this->content);
            $qrCode->setSize($this->size);
            $qrCode->setMargin($this->margin);
            $qrCode->setErrorCorrectionLevel($this->getErrorCorrectionLevel());
            $rgbColor = $this->hexToRgb($this->color);
            $qrCode->setForegroundColor($rgbColor);
            return $qrCode->writeDataUri();
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Outputs the generated QR code directly as a PNG image.
    */
    public function outputQRCode()
    {
        header('Content-Type: image/png');
        echo $this->generateQRCode();
    }
}