php

How to pass a custom variable to a method in a custom QR Code Generator using Chillerlan QRCode Library?


I am currently trying to program a QR code generator using PHP and the QRCode library from Chillerlan.

I have the following problem: I would like to use different module shapes for the layout of the QR codes. Here is an excerpt of my code:

class QRSvgWithLogoAndCustomShapes extends QRMarkupSVG {
    protected function module(int $x, int $y, int $M_TYPE): string {
        if (
            !$this->matrix->isDark($M_TYPE)
            // we're skipping the finder patterns here
            || $this->matrix->checkType($x, $y, QRMatrix::M_FINDER)
            || $this->matrix->checkType($x, $y, QRMatrix::M_FINDER_DOT)
        ) {
            return '';
        }

        // return a heart shape (or any custom shape for that matter)
        // return sprintf('M%1$s %2$s m0.5,0.96 l-0.412,-0.412 a0.3 0.3 0 0 1 0.412,-0.435 a0.3 0.3 0 0 1 0.412,0.435Z', $x, $y);
        // return sprintf('M%1$s %2$s a0.5,0.5 0 1,0 0.001,0', $x, $y);
        // return sprintf('M%1$s %2$s l0.2,0.4 l0.45,0.05 l-0.35,0.25 l0.12,0.48 l-0.45,-0.25 l-0.45,0.25 l0.12,-0.48 l-0.35,-0.25 l0.45,-0.05Z', $x, $y);
        
        return sprintf('M%1$s %2$s a0.5,0.5 0 1,0 0.001,0', $x, $y);
    }
}

class QrCodeGenerator {
    public function qrgenerate(string $data, $modulShape, bool $includeLogo = false) {
        $options = new SVGWithLogoAndCustomShapesOptions;
        
        // SVG logo options (see extended class below)
        if ($includeLogo) {
            $options->svgLogo         = TEMPLATE_PATH.'module/home/github.svg'; // logo from: https://github.com/simple-icons/simple-icons
            $options->svgLogoScale    = 0.25;
            $options->svgLogoCssClass = 'qr-logo dark';
        } else {
            // No logo, so we set svgLogo to an empty string
            $options->svgLogo = '';
        }

        $options->version              = -1;
        $options->versionMin           = 1;
        $options->versionMax           = 40;
        $options->outputType           = QROutputInterface::CUSTOM;
        $options->outputInterface      = QRSvgWithLogoAndCustomShapes::class;
        $options->outputBase64         = false;
        $options->eccLevel             = EccLevel::H;

        $options->drawLightModules     = true; // optional, currently has no effect
        $options->svgUseFillAttributes = true; // optional, currently has no effect

        if ($modulShape == 'circular') {
            $options->drawCircularModules  = true; // true = round modules
            $options->circleRadius         = 0.4; // keep the default value, as it looks good
        }

        $options->connectPaths         = true; // optional, leave it as is for now
        // If using round modules, choose which parts should remain square
        $options->keepAsSquare         = [
            QRMatrix::M_FINDER_DARK,
            QRMatrix::M_FINDER_DOT,
            QRMatrix::M_ALIGNMENT_DARK,
        ];

        $qrcode = new QRCode($options);
        $qrImage = $qrcode->render($data);  // Generate the QR code as a PNG image

        $matrix = $qrcode->getMatrix($qrcode); // Read the used version, $matrix->version() gives the version for storing in the DB
        $version = $matrix->version();

        $qrCodeData = [$data, 'version' => $matrix->version(), $modulShape];
        var_dump($qrImage);
        exit;
        return $qrCodeData;
    }
}

Now, I need to use the $modulShape variable inside the protected function module. How can I achieve this, so that I can check the respective module type via if-else and output the corresponding shape accordingly?


Solution

  • Since you override the method already, you can add a new parameter with a default value:

    protected function module(int $x, int $y, int $M_TYPE, string $modulShape = ''): string {
        //...
    }