Skip to content

Commit

Permalink
Fix static analysis issues
Browse files Browse the repository at this point in the history
endroid committed Oct 24, 2019
1 parent e1c3403 commit 03c71a2
Showing 6 changed files with 81 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['7.2', '7.3']
php-versions: ['7.2', '7.3', '7.4']
steps:
- uses: actions/checkout@v1
- name: Run tests
5 changes: 5 additions & 0 deletions src/Factory/QrCodeFactory.php
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
namespace Endroid\QrCode\Factory;

use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\Exception\ValidationException;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\QrCodeInterface;
use Endroid\QrCode\WriterRegistryInterface;
@@ -79,6 +80,10 @@ public function create(string $text = '', array $options = []): QrCodeInterface
}
}

if (!$qrCode instanceof QrCodeInterface) {
throw new ValidationException('QR Code was messed up by property accessor');
}

return $qrCode;
}

14 changes: 10 additions & 4 deletions src/QrCode.php
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ class QrCode implements QrCodeInterface
/** @var string */
private $logoPath;

/** @var int */
/** @var int|null */
private $logoWidth;

/** @var int|null */
@@ -412,10 +412,16 @@ public function getData(): array

$baconQrCode = Encoder::encode($this->text, $baconErrorCorrectionLevel, $this->encoding);

$matrix = $baconQrCode->getMatrix()->getArray()->toArray();
$baconMatrix = $baconQrCode->getMatrix();

foreach ($matrix as &$row) {
$row = $row->toArray();
$matrix = [];
$columnCount = $baconMatrix->getWidth();
$rowCount = $baconMatrix->getHeight();
for ($rowIndex = 0; $rowIndex < $rowCount; ++$rowIndex) {
$matrix[$rowIndex] = [];
for ($columnIndex = 0; $columnIndex < $columnCount; ++$columnIndex) {
$matrix[$rowIndex][$columnIndex] = $baconMatrix->get($columnIndex, $rowIndex);
}
}

$data = ['matrix' => $matrix];
22 changes: 22 additions & 0 deletions src/Writer/AbstractWriter.php
Original file line number Diff line number Diff line change
@@ -11,10 +11,32 @@

namespace Endroid\QrCode\Writer;

use Endroid\QrCode\Exception\InvalidLogoException;
use Endroid\QrCode\Exception\MissingExtensionException;
use Endroid\QrCode\QrCodeInterface;

abstract class AbstractWriter implements WriterInterface
{
protected function getMimeType(string $path): string
{
if (!function_exists('mime_content_type')) {
throw new MissingExtensionException('You need the ext-fileinfo extension to determine logo mime type');
}

$mimeType = mime_content_type($path);

if (!is_string($mimeType)) {
throw new InvalidLogoException('Could not determine mime type');
}

// Passing mime type image/svg results in invisible images
if ('image/svg' === $mimeType) {
return 'image/svg+xml';
}

return $mimeType;
}

public function writeDataUri(QrCodeInterface $qrCode): string
{
$dataUri = 'data:'.$this->getContentType().';base64,'.base64_encode($this->writeString($qrCode));
22 changes: 15 additions & 7 deletions src/Writer/PngWriter.php
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@

use Endroid\QrCode\Exception\GenerateImageException;
use Endroid\QrCode\Exception\MissingFunctionException;
use Endroid\QrCode\Exception\MissingLogoHeightException;
use Endroid\QrCode\Exception\ValidationException;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCodeInterface;
@@ -24,12 +25,14 @@ public function writeString(QrCodeInterface $qrCode): string
{
$image = $this->createImage($qrCode->getData(), $qrCode);

if (null !== $qrCode->getLogoPath()) {
$image = $this->addLogo($image, $qrCode->getLogoPath(), $qrCode->getLogoWidth(), $qrCode->getLogoHeight());
$logoPath = $qrCode->getLogoPath();
if (null !== $logoPath) {
$image = $this->addLogo($image, $logoPath, $qrCode->getLogoWidth(), $qrCode->getLogoHeight());
}

if (null !== $qrCode->getLabel()) {
$image = $this->addLabel($image, $qrCode->getLabel(), $qrCode->getLabelFontPath(), $qrCode->getLabelFontSize(), $qrCode->getLabelAlignment(), $qrCode->getLabelMargin(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
$label = $qrCode->getLabel();
if (null !== $label) {
$image = $this->addLabel($image, $label, $qrCode->getLabelFontPath(), $qrCode->getLabelFontSize(), $qrCode->getLabelAlignment(), $qrCode->getLabelMargin(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
}

$string = $this->imageToString($image);
@@ -110,10 +113,15 @@ private function createInterpolatedImage($baseImage, array $data, QrCodeInterfac
*/
private function addLogo($sourceImage, string $logoPath, int $logoWidth = null, int $logoHeight = null)
{
$logoImage = imagecreatefromstring((string) file_get_contents($logoPath));
$mimeType = $this->getMimeType($logoPath);
$logoImage = imagecreatefromstring(strval(file_get_contents($logoPath)));

if ('image/svg+xml' === $mimeType && (null === $logoHeight || null === $logoWidth)) {
throw new MissingLogoHeightException('SVG Logos require an explicit height set via setLogoSize($width, $height)');
}

if (!is_resource($logoImage)) {
throw new GenerateImageException('Unable to generate image: check your GD installation');
throw new GenerateImageException('Unable to generate image: check your GD installation or logo path');
}

$logoSourceWidth = imagesx($logoImage);
@@ -131,7 +139,7 @@ private function addLogo($sourceImage, string $logoPath, int $logoWidth = null,
$logoX = imagesx($sourceImage) / 2 - $logoWidth / 2;
$logoY = imagesy($sourceImage) / 2 - $logoHeight / 2;

imagecopyresampled($sourceImage, $logoImage, (int) $logoX, (int) $logoY, 0, 0, $logoWidth, $logoHeight, $logoSourceWidth, $logoSourceHeight);
imagecopyresampled($sourceImage, $logoImage, intval($logoX), intval($logoY), 0, 0, $logoWidth, $logoHeight, $logoSourceWidth, $logoSourceHeight);

return $sourceImage;
}
65 changes: 28 additions & 37 deletions src/Writer/SvgWriter.php
Original file line number Diff line number Diff line change
@@ -12,8 +12,6 @@
namespace Endroid\QrCode\Writer;

use Endroid\QrCode\Exception\GenerateImageException;
use Endroid\QrCode\Exception\InvalidLogoException;
use Endroid\QrCode\Exception\MissingExtensionException;
use Endroid\QrCode\Exception\MissingLogoHeightException;
use Endroid\QrCode\Exception\ValidationException;
use Endroid\QrCode\QrCodeInterface;
@@ -64,8 +62,9 @@ public function writeString(QrCodeInterface $qrCode): string
}
}

if (null !== $qrCode->getLogoPath()) {
$this->addLogo($svg, $data['outer_width'], $data['outer_height'], $qrCode->getLogoPath(), $qrCode->getLogoWidth(), $qrCode->getLogoHeight());
$logoPath = $qrCode->getLogoPath();
if (is_string($logoPath)) {
$this->addLogo($svg, $data['outer_width'], $data['outer_height'], $logoPath, $qrCode->getLogoWidth(), $qrCode->getLogoHeight());
}

$xml = $svg->asXML();
@@ -88,53 +87,45 @@ private function addLogo(SimpleXMLElement $svg, int $imageWidth, int $imageHeigh
$imageData = file_get_contents($logoPath);

if (!is_string($imageData)) {
throw new InvalidLogoException('Invalid logo at path "'.$logoPath.'"');
throw new GenerateImageException('Unable to read image data: check your logo path');
}

if (null === $logoHeight) {
if ('image/svg+xml' === $mimeType) {
throw new MissingLogoHeightException('SVG Logos require an explicit height set via setLogoSize($width, $height)');
} else {
$logoImage = imagecreatefromstring($imageData);
if ('image/svg+xml' === $mimeType && (null === $logoHeight || null === $logoWidth)) {
throw new MissingLogoHeightException('SVG Logos require an explicit height set via setLogoSize($width, $height)');
}

if (!is_resource($logoImage)) {
throw new GenerateImageException('Unable to generate image: check your GD installation');
}
if (null === $logoHeight || null === $logoWidth) {
$logoImage = imagecreatefromstring(strval($imageData));

if (!is_resource($logoImage)) {
throw new GenerateImageException('Unable to generate image: check your GD installation or logo path');
}

$logoSourceWidth = imagesx($logoImage);
$logoSourceHeight = imagesy($logoImage);

$aspectRatio = $logoWidth / imagesx($logoImage);
$logoHeight = intval(imagesy($logoImage) * $aspectRatio);
if (null === $logoWidth) {
$logoWidth = $logoSourceWidth;
}

if (null === $logoHeight) {
$aspectRatio = $logoWidth / $logoSourceWidth;
$logoHeight = intval($logoSourceHeight * $aspectRatio);
}
}

$logoX = $imageWidth / 2 - $logoWidth / 2;
$logoY = $imageHeight / 2 - $logoHeight / 2;

$imageDefinition = $svg->addChild('image');
$imageDefinition->addAttribute('x', strval($imageWidth / 2 - $logoWidth / 2));
$imageDefinition->addAttribute('y', strval($imageHeight / 2 - $logoHeight / 2));
$imageDefinition->addAttribute('x', strval($logoX));
$imageDefinition->addAttribute('y', strval($logoY));
$imageDefinition->addAttribute('width', strval($logoWidth));
$imageDefinition->addAttribute('height', strval($logoHeight));
$imageDefinition->addAttribute('preserveAspectRatio', 'none');
$imageDefinition->addAttribute('xlink:href', 'data:'.$mimeType.';base64,'.base64_encode($imageData));
}

private function getMimeType(string $path): string
{
if (!function_exists('mime_content_type')) {
throw new MissingExtensionException('You need the ext-fileinfo extension to determine logo mime type');
}

$mimeType = mime_content_type($path);

if (!is_string($mimeType)) {
throw new InvalidLogoException('Could not determine mime type');
}

// Passing mime type image/svg results in invisible images
if ('image/svg' === $mimeType) {
return 'image/svg+xml';
}

return $mimeType;
}

private function getOpacity(int $alpha): float
{
$opacity = 1 - $alpha / 127;

0 comments on commit 03c71a2

Please sign in to comment.