mirror of
https://github.com/RobThree/TwoFactorAuth.git
synced 2026-08-17 14:33:05 +00:00
Merge pull request #39 from willpower232/bacon-qr-code-integration
integrate bacon qr code
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace RobThree\Auth\Providers\Qr;
|
||||
|
||||
use BaconQrCode\Writer;
|
||||
use BaconQrCode\Renderer\ImageRenderer;
|
||||
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||
use BaconQrCode\Renderer\RendererStyle\Fill;
|
||||
use BaconQrCode\Renderer\Color\Rgb;
|
||||
use BaconQrCode\Renderer\RendererStyle\EyeFill;
|
||||
|
||||
use BaconQrCode\Renderer\Image\EpsImageBackEnd;
|
||||
use BaconQrCode\Renderer\Image\ImageBackEndInterface;
|
||||
use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
|
||||
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
|
||||
|
||||
class BaconQrCodeProvider implements IQRCodeProvider
|
||||
{
|
||||
private $borderWidth = 4; // default from Bacon QR Code
|
||||
private $backgroundColour;
|
||||
private $foregroundColour;
|
||||
private $format;
|
||||
|
||||
/**
|
||||
* Ensure we using the latest Bacon QR Code and specify default options
|
||||
*
|
||||
* @param int $borderWidth space around the QR code, 4 is the default from Bacon QR Code
|
||||
* @param string $backgroundColour hex reference for the background colour
|
||||
* @param string $foregroundColour hex reference for the foreground colour
|
||||
* @param string $format the desired output, png or svg
|
||||
*/
|
||||
public function __construct($borderWidth = 4, $backgroundColour = '#ffffff', $foregroundColour = '#000000', $format = 'png')
|
||||
{
|
||||
if (! class_exists(ImagickImageBackEnd::class)) {
|
||||
throw new \RuntimeException('Make sure you are using version 2 of Bacon QR Code');
|
||||
}
|
||||
|
||||
$this->borderWidth = $borderWidth;
|
||||
$this->backgroundColour = $this->handleColour($backgroundColour);
|
||||
$this->foregroundColour = $this->handleColour($foregroundColour);
|
||||
$this->format = strtolower($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard functions from IQRCodeProvider
|
||||
*/
|
||||
|
||||
public function getMimeType()
|
||||
{
|
||||
switch ($this->format) {
|
||||
case 'png':
|
||||
return 'image/png';
|
||||
case 'gif':
|
||||
return 'image/gif';
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
return 'image/jpeg';
|
||||
case 'svg':
|
||||
return 'image/svg+xml';
|
||||
case 'eps':
|
||||
return 'application/postscript';
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Unknown MIME-type: %s', $this->format));
|
||||
}
|
||||
|
||||
public function getQRCodeImage($qrText, $size)
|
||||
{
|
||||
switch ($this->format) {
|
||||
case 'svg':
|
||||
$backend = new SvgImageBackEnd;
|
||||
break;
|
||||
case 'eps':
|
||||
$backend = new EpsImageBackEnd;
|
||||
break;
|
||||
default:
|
||||
$backend = new ImagickImageBackEnd($this->format);
|
||||
}
|
||||
|
||||
$output = $this->getQRCodeByBackend($qrText, $size, $backend);
|
||||
|
||||
if ($this->format == 'svg') {
|
||||
$svg = explode("\n", $output);
|
||||
return $svg[1];
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract QR code generation function
|
||||
* providing colour changing support
|
||||
*/
|
||||
private function getQRCodeByBackend($qrText, $size, ImageBackEndInterface $backend)
|
||||
{
|
||||
$rendererStyleArgs = array($size, $this->borderWidth);
|
||||
|
||||
if (is_array($this->foregroundColour) && is_array($this->backgroundColour)) {
|
||||
$rendererStyleArgs = array_merge($rendererStyleArgs, array(
|
||||
null,
|
||||
null,
|
||||
Fill::withForegroundColor(
|
||||
new Rgb(...$this->backgroundColour),
|
||||
new Rgb(...$this->foregroundColour),
|
||||
new EyeFill(null, null),
|
||||
new EyeFill(null, null),
|
||||
new EyeFill(null, null)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
$writer = new Writer(new ImageRenderer(
|
||||
new RendererStyle(...$rendererStyleArgs),
|
||||
$backend
|
||||
));
|
||||
|
||||
return $writer->writeString($qrText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure colour is an array of three values but also
|
||||
* accept a string and assume its a 3 or 6 character hex
|
||||
*/
|
||||
private function handleColour($colour)
|
||||
{
|
||||
if (is_string($colour) && $colour[0] == '#') {
|
||||
$hexToRGB = function ($input) {
|
||||
// split the array into three chunks
|
||||
$split = str_split(trim($input, '#'), strlen($input) / 3);
|
||||
|
||||
// cope with three character hex reference
|
||||
// three characters plus a # = 4
|
||||
if (strlen($input) == 4) {
|
||||
array_walk($split, function (&$character) {
|
||||
$character = str_repeat($character, 2);
|
||||
});
|
||||
}
|
||||
|
||||
// convert hex to rgb
|
||||
return array_map('hexdec', $split);
|
||||
};
|
||||
|
||||
return $hexToRGB($colour);
|
||||
}
|
||||
|
||||
if (is_array($colour) && count($colour) == 3) {
|
||||
return $colour;
|
||||
}
|
||||
|
||||
throw new \RuntimeException('Invalid colour value');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user