Skip to content

Commit

Permalink
Use test lib
Browse files Browse the repository at this point in the history
  • Loading branch information
endroid committed May 5, 2019
1 parent 7823bad commit 3c96919
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 45 deletions.
9 changes: 4 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
language: php

php:
- 7.1
- 7.2
- 7.3
- '7.2'
- '7.3'

matrix:
fast_finish: true
Expand All @@ -16,10 +15,10 @@ before_install:
- composer self-update

install:
- composer update --no-interaction --prefer-dist $COMPOSER_FLAGS
- composer update --no-interaction --prefer-source $COMPOSER_FLAGS

script:
- vendor/bin/phpunit
- vendor/bin/test

notifications:
email:
Expand Down
14 changes: 6 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,18 @@
}
],
"require": {
"php": ">=7.1",
"php": ">=7.2",
"ext-gd": "*",
"bacon/bacon-qr-code": "^2.0",
"endroid/installer": "^1.0.3",
"endroid/installer": "^1.1.5",
"khanamiryan/qrcode-detector-decoder": "^1.0.2",
"myclabs/php-enum": "^1.5",
"symfony/options-resolver": "^2.7|^3.0|^4.0",
"symfony/property-access": "^2.7|^3.0|^4.0"
"symfony/http-foundation": "^3.4|^4.0",
"symfony/options-resolver": "^3.4|^4.0",
"symfony/property-access": "^3.4|^4.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7|^6.0"
},
"suggest": {
"symfony/http-foundation": "Install if you want to use QrCodeResponse"
"endroid/test": "^1.1.4"
},
"autoload": {
"psr-4": {
Expand Down
8 changes: 0 additions & 8 deletions phpunit.xml.dist

This file was deleted.

16 changes: 16 additions & 0 deletions src/Exception/GenerateImageException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

/*
* (c) Jeroen van den Enden <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Endroid\QrCode\Exception;

class GenerateImageException extends QrCodeException
{
}
16 changes: 16 additions & 0 deletions src/Exception/InvalidLogoException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

/*
* (c) Jeroen van den Enden <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Endroid\QrCode\Exception;

class InvalidLogoException extends QrCodeException
{
}
14 changes: 7 additions & 7 deletions src/QrCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public function setLogoPath(string $logoPath): void
{
$logoPath = realpath($logoPath);

if (!is_file($logoPath)) {
if (false === $logoPath || !is_file($logoPath)) {
throw new InvalidPathException('Invalid logo path: '.$logoPath);
}

Expand Down Expand Up @@ -242,23 +242,23 @@ public function setLabelFontSize(int $labelFontSize): void
$this->labelFontSize = $labelFontSize;
}

public function getLabelFontSize(): ?int
public function getLabelFontSize(): int
{
return $this->labelFontSize;
}

public function setLabelFontPath(string $labelFontPath): void
{
$resolvedLabelFontPath = realpath($labelFontPath);
$resolvedLabelFontPath = (string) realpath($labelFontPath);

if (!is_string($resolvedLabelFontPath) || !is_file($resolvedLabelFontPath)) {
if (!is_file($resolvedLabelFontPath)) {
throw new InvalidPathException('Invalid label font path: '.$labelFontPath);
}

$this->labelFontPath = $resolvedLabelFontPath;
}

public function getLabelFontPath(): ?string
public function getLabelFontPath(): string
{
return $this->labelFontPath;
}
Expand All @@ -268,7 +268,7 @@ public function setLabelAlignment(string $labelAlignment): void
$this->labelAlignment = new LabelAlignment($labelAlignment);
}

public function getLabelAlignment(): ?string
public function getLabelAlignment(): string
{
return $this->labelAlignment->getValue();
}
Expand All @@ -278,7 +278,7 @@ public function setLabelMargin(array $labelMargin): void
$this->labelMargin = array_merge($this->labelMargin, $labelMargin);
}

public function getLabelMargin(): ?array
public function getLabelMargin(): array
{
return $this->labelMargin;
}
Expand Down
8 changes: 4 additions & 4 deletions src/QrCodeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ public function getLogoHeight(): ?int;

public function getLabel(): ?string;

public function getLabelFontPath(): ?string;
public function getLabelFontPath(): string;

public function getLabelFontSize(): ?int;
public function getLabelFontSize(): int;

public function getLabelAlignment(): ?string;
public function getLabelAlignment(): string;

public function getLabelMargin(): ?array;
public function getLabelMargin(): array;

public function getValidateResult(): bool;

Expand Down
4 changes: 0 additions & 4 deletions src/Response/QrCodeResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
use Endroid\QrCode\QrCodeInterface;
use Symfony\Component\HttpFoundation\Response;

if (!class_exists(Response::class)) {
throw new \Exception('QrCodeResponse requires symfony/http-foundation');
}

class QrCodeResponse extends Response
{
public function __construct(QrCodeInterface $qrCode)
Expand Down
32 changes: 26 additions & 6 deletions src/Writer/PngWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Endroid\QrCode\Writer;

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

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

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

Expand Down Expand Up @@ -59,14 +60,19 @@ private function createImage(array $data, QrCodeInterface $qrCode)
private function createBaseImage(int $baseSize, array $data, QrCodeInterface $qrCode)
{
$image = imagecreatetruecolor($data['block_count'] * $baseSize, $data['block_count'] * $baseSize);

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

$foregroundColor = imagecolorallocatealpha($image, $qrCode->getForegroundColor()['r'], $qrCode->getForegroundColor()['g'], $qrCode->getForegroundColor()['b'], $qrCode->getForegroundColor()['a']);
$backgroundColor = imagecolorallocatealpha($image, $qrCode->getBackgroundColor()['r'], $qrCode->getBackgroundColor()['g'], $qrCode->getBackgroundColor()['b'], $qrCode->getBackgroundColor()['a']);
imagefill($image, 0, 0, $backgroundColor);

foreach ($data['matrix'] as $row => $values) {
foreach ($values as $column => $value) {
if (1 === $value) {
imagefilledrectangle($image, $column * $baseSize, $row * $baseSize, ($column + 1) * $baseSize, ($row + 1) * $baseSize, $foregroundColor);
imagefilledrectangle($image, $column * $baseSize, $row * $baseSize, intval(($column + 1) * $baseSize), intval(($row + 1) * $baseSize), $foregroundColor);
}
}
}
Expand All @@ -77,6 +83,11 @@ private function createBaseImage(int $baseSize, array $data, QrCodeInterface $qr
private function createInterpolatedImage($baseImage, array $data, QrCodeInterface $qrCode)
{
$image = imagecreatetruecolor($data['outer_width'], $data['outer_height']);

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

$backgroundColor = imagecolorallocatealpha($image, $qrCode->getBackgroundColor()['r'], $qrCode->getBackgroundColor()['g'], $qrCode->getBackgroundColor()['b'], $qrCode->getBackgroundColor()['a']);
imagefill($image, 0, 0, $backgroundColor);
imagecopyresampled($image, $baseImage, (int) $data['margin_left'], (int) $data['margin_left'], 0, 0, (int) $data['inner_width'], (int) $data['inner_height'], imagesx($baseImage), imagesy($baseImage));
Expand All @@ -87,7 +98,12 @@ private function createInterpolatedImage($baseImage, array $data, QrCodeInterfac

private function addLogo($sourceImage, string $logoPath, int $logoWidth = null, int $logoHeight = null)
{
$logoImage = imagecreatefromstring(file_get_contents($logoPath));
$logoImage = imagecreatefromstring((string) file_get_contents($logoPath));

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

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

Expand Down Expand Up @@ -125,6 +141,11 @@ private function addLabel($sourceImage, string $label, string $labelFontPath, in

// Create empty target image
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);

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

$foregroundColor = imagecolorallocate($targetImage, $foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
$backgroundColor = imagecolorallocate($targetImage, $backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
imagefill($targetImage, 0, 0, $backgroundColor);
Expand Down Expand Up @@ -154,9 +175,8 @@ private function imageToString($image): string
{
ob_start();
imagepng($image);
$string = ob_get_clean();

return $string;
return (string) ob_get_clean();
}

public static function getContentType(): string
Expand Down
25 changes: 22 additions & 3 deletions src/Writer/SvgWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

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;
Expand Down Expand Up @@ -62,12 +64,16 @@ public function writeString(QrCodeInterface $qrCode): string
}
}

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

$xml = $svg->asXML();

if (!is_string($xml)) {
throw new GenerateImageException('Unable to save SVG XML');
}

$options = $qrCode->getWriterOptions();
if (isset($options['exclude_xml_declaration']) && $options['exclude_xml_declaration']) {
$xml = str_replace("<?xml version=\"1.0\"?>\n", '', $xml);
Expand All @@ -76,16 +82,25 @@ public function writeString(QrCodeInterface $qrCode): string
return $xml;
}

private function addLogo(SimpleXMLElement $svg, int $imageWidth, int $imageHeight, string $logoPath, int $logoWidth, int $logoHeight = null): void
private function addLogo(SimpleXMLElement $svg, int $imageWidth, int $imageHeight, string $logoPath, int $logoWidth = null, int $logoHeight = null): void
{
$mimeType = $this->getMimeType($logoPath);
$imageData = file_get_contents($logoPath);

if (!is_string($imageData)) {
throw new InvalidLogoException('Invalid logo at path "'.$logoPath.'"');
}

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 (!is_resource($logoImage)) {
throw new GenerateImageException('Unable to generate image: check your GD installation');
}

$aspectRatio = $logoWidth / imagesx($logoImage);
$logoHeight = intval(imagesy($logoImage) * $aspectRatio);
}
Expand All @@ -103,11 +118,15 @@ private function addLogo(SimpleXMLElement $svg, int $imageWidth, int $imageHeigh
private function getMimeType(string $path): string
{
if (!function_exists('mime_content_type')) {
throw new MissingExtensionException('You need the ext-fileinfo extension to determine the mime 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';
Expand Down

0 comments on commit 3c96919

Please sign in to comment.