Browse Source

:octocat: file caching rework/cleanup

smiley 2 years ago
parent
commit
ecdd81a0cb

+ 1 - 3
examples/imageWithLogo.php

@@ -59,9 +59,7 @@ class QRImageWithLogo extends QRGdImage{
 
 		$imageData = $this->dumpImage();
 
-		if($file !== null){
-			$this->saveToFile($imageData, $file);
-		}
+		$this->saveToFile($imageData, $file);
 
 		if($this->options->imageBase64){
 			$imageData = $this->toBase64DataURI($imageData, 'image/'.$this->options->outputType);

+ 1 - 3
examples/imageWithText.php

@@ -39,9 +39,7 @@ class QRImageWithText extends QRGdImage{
 
 		$imageData = $this->dumpImage();
 
-		if($file !== null){
-			$this->saveToFile($imageData, $file);
-		}
+		$this->saveToFile($imageData, $file);
 
 		if($this->options->imageBase64){
 			$imageData = $this->toBase64DataURI($imageData, 'image/'.$this->options->outputType);

+ 1 - 4
src/Output/QREps.php

@@ -66,7 +66,6 @@ class QREps extends QROutputAbstract{
 	 * @inheritDoc
 	 */
 	public function dump(string $file = null):string{
-		$file ??= $this->options->cachefile;
 
 		$eps = [
 			// main header
@@ -103,9 +102,7 @@ class QREps extends QROutputAbstract{
 
 		$data = implode("\n", $eps);
 
-		if($file !== null){
-			$this->saveToFile($data, $file);
-		}
+		$this->saveToFile($data, $file);
 
 		return $data;
 	}

+ 1 - 4
src/Output/QRFpdf.php

@@ -90,7 +90,6 @@ class QRFpdf extends QROutputAbstract{
 	 * @return string|\FPDF
 	 */
 	public function dump(string $file = null){
-		$file ??= $this->options->cachefile;
 
 		$fpdf = new FPDF('P', $this->options->fpdfMeasureUnit, [$this->length, $this->length]);
 		$fpdf->AddPage();
@@ -132,9 +131,7 @@ class QRFpdf extends QROutputAbstract{
 
 		$pdfData = $fpdf->Output('S');
 
-		if($file !== null){
-			$this->saveToFile($pdfData, $file);
-		}
+		$this->saveToFile($pdfData, $file);
 
 		if($this->options->imageBase64){
 			$pdfData = $this->toBase64DataURI($pdfData, 'application/pdf');

+ 1 - 5
src/Output/QRGdImage.php

@@ -104,8 +104,6 @@ class QRGdImage extends QROutputAbstract{
 			throw new ErrorException($msg, 0, $severity, $file, $line);
 		});
 
-		$file ??= $this->options->cachefile;
-
 		// we're scaling the image up in order to draw crisp round circles, otherwise they appear square-y on small scales
 		if($this->options->drawCircularModules && $this->options->scale <= 20){
 			$this->length  = ($this->length + 2) * 10;
@@ -156,9 +154,7 @@ class QRGdImage extends QROutputAbstract{
 
 		$imageData = $this->dumpImage();
 
-		if($file !== null){
-			$this->saveToFile($imageData, $file);
-		}
+		$this->saveToFile($imageData, $file);
 
 		if($this->options->imageBase64){
 			$imageData = $this->toBase64DataURI($imageData, 'image/'.$this->options->outputType);

+ 1 - 4
src/Output/QRImagick.php

@@ -70,7 +70,6 @@ class QRImagick extends QROutputAbstract{
 	 * @return string|\Imagick
 	 */
 	public function dump(string $file = null){
-		$file          ??= $this->options->cachefile;
 		$this->imagick = new Imagick;
 
 		$bgColor = $this->options->imageTransparent ? 'transparent' : 'white';
@@ -92,9 +91,7 @@ class QRImagick extends QROutputAbstract{
 
 		$this->imagick->destroy();
 
-		if($file !== null){
-			$this->saveToFile($imageData, $file);
-		}
+		$this->saveToFile($imageData, $file);
 
 		return $imageData;
 	}

+ 2 - 7
src/Output/QRMarkup.php

@@ -42,14 +42,9 @@ abstract class QRMarkup extends QROutputAbstract{
 	 * @inheritDoc
 	 */
 	public function dump(string $file = null):string{
-		$file       ??= $this->options->cachefile;
-		$saveToFile   = $file !== null;
+		$data = $this->createMarkup($file !== null);
 
-		$data = $this->createMarkup($saveToFile);
-
-		if($saveToFile){
-			$this->saveToFile($data, $file);
-		}
+		$this->saveToFile($data, $file);
 
 		return $data;
 	}

+ 7 - 3
src/Output/QROutputAbstract.php

@@ -122,14 +122,18 @@ abstract class QROutputAbstract implements QROutputInterface{
 	}
 
 	/**
-	 * saves the qr data to a file
+	 * Saves the qr $data to a $file. If $file is null, nothing happens.
 	 *
 	 * @see file_put_contents()
-	 * @see \chillerlan\QRCode\QROptions::cachefile
+	 * @see \chillerlan\QRCode\QROptions::$cachefile
 	 *
 	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
 	 */
-	protected function saveToFile(string $data, string $file):void{
+	protected function saveToFile(string $data, string $file = null):void{
+
+		if($file === null){
+			return;
+		}
 
 		if(!is_writable(dirname($file))){
 			throw new QRCodeOutputException(sprintf('Cannot write data to cache file: %s', $file));

+ 6 - 0
src/Output/QROutputInterface.php

@@ -89,6 +89,12 @@ interface QROutputInterface{
 	/**
 	 * generates the output, optionally dumps it to a file, and returns it
 	 *
+	 * please note that the value of QROptions::$cachefile is already evaluated at this point.
+	 * if the output module is invoked manually, it has no effect at all.
+	 * you need to supply the $file parameter here in that case (or handle the option value in your custom output module).
+	 *
+	 * @see \chillerlan\QRCode\QRCode::renderMatrix()
+	 *
 	 * @return mixed
 	 */
 	public function dump(string $file = null);

+ 1 - 4
src/Output/QRString.php

@@ -45,7 +45,6 @@ class QRString extends QROutputAbstract{
 	 * @inheritDoc
 	 */
 	public function dump(string $file = null):string{
-		$file ??= $this->options->cachefile;
 
 		switch($this->options->outputType){
 			case QROutputInterface::STRING_TEXT:
@@ -56,9 +55,7 @@ class QRString extends QROutputAbstract{
 				$data = $this->json();
 		}
 
-		if($file !== null){
-			$this->saveToFile($data, $file);
-		}
+		$this->saveToFile($data, $file);
 
 		return $data;
 	}

+ 2 - 1
src/QRCode.php

@@ -223,7 +223,7 @@ class QRCode{
 	 * @return mixed
 	 */
 	public function renderMatrix(QRMatrix $matrix, string $file = null){
-		return $this->initOutputInterface($matrix)->dump($file);
+		return $this->initOutputInterface($matrix)->dump($file ?? $this->options->cachefile);
 	}
 
 	/**
@@ -284,6 +284,7 @@ class QRCode{
 		if(!in_array(QROutputInterface::class, class_implements($outputInterface))){
 			throw new QRCodeOutputException('output module does not implement QROutputInterface');
 		}
+
 		return new $outputInterface($this->options, $matrix);
 	}
 

+ 2 - 0
src/QROptionsTrait.php

@@ -93,6 +93,8 @@ trait QROptionsTrait{
 
 	/**
 	 * /path/to/cache.file
+	 *
+	 * please note that the $file parameter in QRCode::render*() takes precedence over the $cachefile value
 	 */
 	protected ?string $cachefile = null;
 

+ 5 - 5
tests/Output/QROutputTestAbstract.php

@@ -63,9 +63,8 @@ abstract class QROutputTestAbstract extends TestCase{
 		$this->expectException(QRCodeOutputException::class);
 		$this->expectExceptionMessage('Cannot write data to cache file: /foo/bar.test');
 
-		$this->options->cachefile = '/foo/bar.test';
 		$this->outputInterface = new $this->FQN($this->options, $this->matrix);
-		$this->outputInterface->dump();
+		$this->outputInterface->dump('/foo/bar.test');
 	}
 
 	/**
@@ -81,12 +80,13 @@ abstract class QROutputTestAbstract extends TestCase{
 	 * coverage of the built-in output modules
 	 */
 	public function testRenderToCacheFile():void{
-		$this->options->cachefile   = $this->builddir.'/test.'.$this->type;
 		$this->options->imageBase64 = false;
 		$this->outputInterface      = new $this->FQN($this->options, $this->matrix);
-		$data                       = $this->outputInterface->dump(); // creates the cache file
+		// create the cache file
+		$file = $this->builddir.'/test.output.'.$this->type;
+		$data = $this->outputInterface->dump($file);
 
-		$this::assertSame($data, file_get_contents($this->options->cachefile));
+		$this::assertSame($data, file_get_contents($file));
 	}
 
 }

+ 26 - 0
tests/QRCodeTest.php

@@ -14,6 +14,7 @@ use chillerlan\QRCode\{QROptions, QRCode};
 use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface};
 use PHPUnit\Framework\TestCase;
 use stdClass;
+use function file_get_contents;
 
 /**
  * Tests basic functions of the QRCode class
@@ -22,6 +23,7 @@ final class QRCodeTest extends TestCase{
 
 	private QRCode    $qrcode;
 	private QROptions $options;
+	private string    $builddir = __DIR__.'/../.build/output_test';
 
 	/**
 	 * invoke test instances
@@ -68,4 +70,28 @@ final class QRCodeTest extends TestCase{
 		$this->qrcode->setOptions($this->options)->render('test');
 	}
 
+	/**
+	 * Tests if an exception is thrown when trying to write a cache file to an invalid destination
+	 */
+	public function testSaveException():void{
+		$this->expectException(QRCodeOutputException::class);
+		$this->expectExceptionMessage('Cannot write data to cache file: /foo/bar.test');
+
+		$this->options->cachefile = '/foo/bar.test';
+
+		$this->qrcode->setOptions($this->options)->render('test');
+	}
+
+	/**
+	 * Tests if a cache file is properly saved in the given path
+	 */
+	public function testRenderToCacheFile():void{
+		$this->options->cachefile   = $this->builddir.'/test.cache.svg';
+		$this->options->imageBase64 = false;
+		// create the cache file
+		$data = $this->qrcode->setOptions($this->options)->render('test');
+
+		$this::assertSame($data, file_get_contents($this->options->cachefile));
+	}
+
 }