diff --git a/.phpcs.xml b/.phpcs.xml index 8e0c4b5..2ad75ca 100644 --- a/.phpcs.xml +++ b/.phpcs.xml @@ -2,13 +2,11 @@ Custom rule set. - . + src test - autoload.php docs/* build/* - coverage/* test/config.php webroot/imgs.php webroot/imgp.php diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index c0cbbc9..2fdd796 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -6,6 +6,8 @@ use Behat\Behat\Context\SnippetAcceptingContext; use Behat\Gherkin\Node\PyStringNode; use Behat\Gherkin\Node\TableNode; +require __DIR__ . "/assert.php"; + /** * Defines application features from the specific context. */ @@ -76,7 +78,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { //echo $this->url; $res = file_get_contents($this->url); - PHPUnit_Framework_Assert::assertNotEquals(false, $res); + assertNotEquals(false, $res); $this->imageString = $res; $this->headers = $http_response_header; @@ -94,10 +96,10 @@ class FeatureContext implements Context, SnippetAcceptingContext public function getImageAsJson() { $res = file_get_contents($this->url . "&json"); - PHPUnit_Framework_Assert::assertNotEquals(false, $res); + assertNotEquals(false, $res); $res = json_decode($res, true); - PHPUnit_Framework_Assert::assertNotEquals(null, $res); + assertNotEquals(null, $res); $this->imageJSON = $res; } @@ -111,7 +113,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { //echo $this->url; $res = get_headers($this->url); - PHPUnit_Framework_Assert::assertNotEquals(false, $res); + assertNotEquals(false, $res); $this->headers = $http_response_header; } @@ -123,7 +125,7 @@ class FeatureContext implements Context, SnippetAcceptingContext */ public function returnsStatusCode($arg1) { - PHPUnit_Framework_Assert::assertNotEquals( + assertNotEquals( false, strpos($this->headers[0], $arg1) ); @@ -136,19 +138,19 @@ class FeatureContext implements Context, SnippetAcceptingContext private function compareImageJsonToHeaders() { $contentLength = "Content-Length: " . $this->imageJSON["size"]; - PHPUnit_Framework_Assert::assertContains( + assertContains( $contentLength, $this->headers ); $contentType = "Content-Type: " . $this->imageJSON["mimeType"]; - PHPUnit_Framework_Assert::assertContains( + assertContains( $contentType, $this->headers ); $lastModified = "Last-Modified: " . $this->imageJSON["cacheGmdate"] . " GMT"; - PHPUnit_Framework_Assert::assertContains( + assertContains( $lastModified, $this->headers ); @@ -162,10 +164,10 @@ class FeatureContext implements Context, SnippetAcceptingContext private function compareImageJsonToSavedJson($file) { $res = file_get_contents("$file.json"); - PHPUnit_Framework_Assert::assertNotEquals(false, $res); + assertNotEquals(false, $res); $res = json_decode($res, true); - PHPUnit_Framework_Assert::assertNotEquals(null, $res); + assertNotEquals(null, $res); $keys = [ "mimeType", @@ -179,7 +181,7 @@ class FeatureContext implements Context, SnippetAcceptingContext if (array_key_exists($key, $res) && array_key_exists($key, $this->imageJSON) ) { - PHPUnit_Framework_Assert::assertEquals( + assertEquals( $res[$key], $this->imageJSON[$key] ); @@ -196,9 +198,9 @@ class FeatureContext implements Context, SnippetAcceptingContext { $base = __DIR__ . "/../img"; $res = file_get_contents("$base/$arg1"); - PHPUnit_Framework_Assert::assertNotEquals(false, $res); + assertNotEquals(false, $res); - PHPUnit_Framework_Assert::assertEquals($this->imageString, $res); + assertEquals($this->imageString, $res); $this->compareImageJsonToHeaders(); $this->compareImageJsonToSavedJson("$base/$arg1"); diff --git a/features/bootstrap/assert.php b/features/bootstrap/assert.php new file mode 100644 index 0000000..559bd05 --- /dev/null +++ b/features/bootstrap/assert.php @@ -0,0 +1,32 @@ +log("Re-calculate image dimensions, newWidth x newHeigh was: " . $this->newWidth . " x " . $this->newHeight); + $this->log("Re-calculate image dimensions, newWidth x newHeigh was: " + . $this->newWidth + . " x " + . $this->newHeight); $this->newWidth = $this->newWidthOrig; $this->newHeight = $this->newHeightOrig; @@ -1586,7 +1589,6 @@ class CImage } switch ($pngType) { - case self::PNG_GREYSCALE: $text = "PNG is type 0, Greyscale$transparent"; break; @@ -1754,7 +1756,6 @@ class CImage // Only use a specified area of the image, $this->offset is defining the area to use if (isset($this->offset)) { - $this->log("Offset for area to use, cropping it width={$this->offset['width']}, height={$this->offset['height']}, start_x={$this->offset['left']}, start_y={$this->offset['top']}"); $img = $this->CreateImageKeepTransparency($this->offset['width'], $this->offset['height']); imagecopy($img, $this->image, 0, 0, $this->offset['left'], $this->offset['top'], $this->offset['width'], $this->offset['height']); @@ -1764,7 +1765,6 @@ class CImage } if ($this->crop) { - // Do as crop, take only part of image $this->log("Cropping area width={$this->crop['width']}, height={$this->crop['height']}, start_x={$this->crop['start_x']}, start_y={$this->crop['start_y']}"); $img = $this->CreateImageKeepTransparency($this->crop['width'], $this->crop['height']); @@ -1781,11 +1781,10 @@ class CImage } if ($this->cropToFit) { - // Resize by crop to fit $this->log("Resizing using strategy - Crop to fit"); - if (!$this->upscale + if (!$this->upscale && ($this->width < $this->newWidth || $this->height < $this->newHeight)) { $this->log("Resizing - smaller image, do not upscale."); @@ -1842,9 +1841,7 @@ class CImage $this->image = $imageResized; $this->width = $this->newWidth; $this->height = $this->newHeight; - } elseif ($this->fillToFit) { - // Resize by fill to fit $this->log("Resizing using strategy - Fill to fit"); @@ -1864,13 +1861,11 @@ class CImage if (!$this->upscale && ($this->width < $this->newWidth && $this->height < $this->newHeight) ) { - $this->log("Resizing - smaller image, do not upscale."); $posX = round(($this->newWidth - $this->width) / 2); $posY = round(($this->newHeight - $this->height) / 2); $imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight); imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->width, $this->height); - } else { $imgPreFill = $this->CreateImageKeepTransparency($this->fillWidth, $this->fillHeight); $imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight); @@ -1881,9 +1876,7 @@ class CImage $this->image = $imageResized; $this->width = $this->newWidth; $this->height = $this->newHeight; - } elseif (!($this->newWidth == $this->width && $this->newHeight == $this->height)) { - // Resize it $this->log("Resizing, new height and/or width"); @@ -1948,12 +1941,10 @@ class CImage // Apply filters if (isset($this->filters) && is_array($this->filters)) { - foreach ($this->filters as $filter) { $this->log("Applying filter {$filter['type']}."); switch ($filter['argc']) { - case 0: imagefilter($this->image, $filter['type']); break; @@ -2298,7 +2289,6 @@ class CImage $img = isset($img) ? $img : $this->image; if ($this->bgColorDefault) { - $red = $this->bgColorDefault['red']; $green = $this->bgColorDefault['green']; $blue = $this->bgColorDefault['blue']; @@ -2311,7 +2301,6 @@ class CImage } return $color; - } else { return 0; } @@ -2339,16 +2328,13 @@ class CImage : -1; if ($index != -1) { - imagealphablending($img, true); $transparent = imagecolorsforindex($this->image, $index); $color = imagecolorallocatealpha($img, $transparent['red'], $transparent['green'], $transparent['blue'], $transparent['alpha']); imagefill($img, 0, 0, $color); $index = imagecolortransparent($img, $color); $this->Log("Detected transparent color = " . implode(", ", $transparent) . " at index = $index"); - } elseif ($this->bgColorDefault) { - $color = $this->getBackgroundColor($img); imagefill($img, 0, 0, $color); $this->Log("Filling image with background color."); @@ -2374,7 +2360,7 @@ class CImage $this->jpegOptimizeCmd = null; } - if (array_key_exists("png_lossy", $options) + if (array_key_exists("png_lossy", $options) && $options['png_lossy'] !== false) { $this->pngLossy = $options['png_lossy']; $this->pngLossyCmd = $options['png_lossy_cmd']; @@ -2444,7 +2430,6 @@ class CImage $type = $this->getTargetImageExtension(); $this->Log("Saving image as " . $type); switch ($type) { - case 'jpeg': case 'jpg': $this->Log("Saving image as JPEG to cache using quality = {$this->quality}."); @@ -2716,7 +2701,6 @@ class CImage if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) { - if ($this->verbose) { $this->log("304 not modified"); $this->verboseOutput(); @@ -2727,9 +2711,7 @@ class CImage if (CIMAGE_DEBUG) { trace(__CLASS__ . " 304"); } - } else { - $this->loadImageDetails($file); $mime = $this->getMimeType(); $size = filesize($file); diff --git a/src/CImage/CImageResizer.php b/src/CImage/CImageResizer.php index 3d27ca0..4dd0c2b 100644 --- a/src/CImage/CImageResizer.php +++ b/src/CImage/CImageResizer.php @@ -385,7 +385,6 @@ class CImageResizer // Both null, use source as base for target if (is_null($this->targetWidth) && is_null($this->targetHeight)) { - $this->targetWidth = ($this->aspectRatio >= 1) ? $this->srcWidth : null; @@ -395,12 +394,10 @@ class CImageResizer : $this->srcHeight; $this->log(" Using source as base {$this->targetWidth}x{$this->targetHeight}"); - } // Both or either set, calculate the other if (isset($this->targetWidth) && isset($this->targetHeight)) { - $this->targetWidth = ($this->aspectRatio >= 1) ? $this->targetWidth : $this->targetHeight * $this->aspectRatio; @@ -410,17 +407,12 @@ class CImageResizer : $this->targetHeight; $this->log(" New target width height {$this->targetWidth}x{$this->targetHeight}"); - } elseif (isset($this->targetWidth)) { - $this->targetHeight = $this->targetWidth / $this->aspectRatio; $this->log(" New target height x{$this->targetHeight}"); - } elseif (isset($this->targetHeight)) { - $this->targetWidth = $this->targetHeight * $this->aspectRatio; $this->log(" New target width {$this->targetWidth}x"); - } return $this; @@ -518,28 +510,21 @@ class CImageResizer $ratio = $both ? $tw / $th : null; if (is_null($tw) && is_null($th)) { - // No tw/th use sw/sh $tw = $sw; $th = $sh; $this->log(" New tw x th {$tw}x{$th}"); - } elseif (isset($tw) && is_null($th)) { - // Keep aspect ratio, make th based on tw $this->respectUpscale($tw, $sw); $th = $tw / $ar; $this->log(" New th x{$th}"); - } elseif (is_null($tw) && isset($th)) { - // Keep aspect ratio, make tw based on th $this->respectUpscale($th, $sh); $tw = $th * $ar; $this->log(" New tw {$tw}x"); - } elseif ($rs === CImageResizer::KEEP_RATIO && $both) { - // Keep aspect ratio, make fit in box not larger than tw/th $this->log(" Keep ratio, ratio target=$ratio, source=$ar"); @@ -555,9 +540,7 @@ class CImageResizer $this->respectUpscale($tw, $sw); $this->respectUpscale($th, $sh); } - } elseif ($rs === CImageResizer::STRETCH && $both) { - // Stretch to fit, leave as is $this->log(" Stretch"); @@ -570,9 +553,7 @@ class CImageResizer $dy = ($th - $dh) / 2; $this->log(" Destination area dx=$dx, dy=$dy, dw=$dw, dh=$dh"); - } elseif ($rs === CImageResizer::CROP_TO_FIT && $both) { - // Crop to fit image in box $this->log(" Crop to fit, ratio target=$ratio, source=$ar"); @@ -607,9 +588,7 @@ class CImageResizer $this->log(" Parts cx=$cx, cy=$cy, cw=$cw, ch=$ch"); $this->log(" Destination area dx=$dx, dy=$dy, dw=$dw, dh=$dh"); - } elseif ($rs === CImageResizer::FILL_TO_FIT && $both) { - // Fill to fit image in box $this->log(" Fill to fit, ratio target=$ratio, source=$ar"); $dw = $tw; @@ -647,10 +626,12 @@ class CImageResizer $this->cropWidth = round($cw); $this->cropHeight = round($ch); - $this->log(" Target dimension (after) {$this->targetWidth}x{$this->targetHeight}."); - $this->log(" Crop area {$this->cropX}x{$this->cropY} by {$this->cropWidth}x{$this->cropHeight}."); - $this->log(" Destination area {$this->destinationX}x{$this->destinationY} by {$this->destinationWidth}x{$this->destinationHeight}."); - + $str = <<targetWidth}x{$this->targetHeight}. + Crop area {$this->cropX}x{$this->cropY} by {$this->cropWidth}x{$this->cropHeight}. + Destination area {$this->destinationX}x{$this->destinationY} by {$this->destinationWidth}x{$this->destinationHeight}. +EOD; + $this->log($str); /* diff --git a/src/CImage/Exception.php b/src/CImage/Exception.php new file mode 100644 index 0000000..da5c229 --- /dev/null +++ b/src/CImage/Exception.php @@ -0,0 +1,22 @@ +img.php: Uncaught exception:

" - . $exception->getMessage() - . "

"
-        . $exception->getTraceAsString()
-        . "
", - 500 - ); -}); - - - /** * Get input from query string or return default value if not set. * diff --git a/test/CImageResizerByAspectRatioTest.php b/test/CImageResizerByAspectRatioTest.php index 04fad64..048eeff 100644 --- a/test/CImageResizerByAspectRatioTest.php +++ b/test/CImageResizerByAspectRatioTest.php @@ -50,8 +50,15 @@ class CImageResizerByAspectRatioTest extends \PHPUnit_Framework_TestCase * * @return void */ - public function testResize1($aspectRatio, $srcWidth, $srcHeight, $targetWidth, $targetHeight, $expectedWidth, $expectedHeight) - { + public function testResize1( + $aspectRatio, + $srcWidth, + $srcHeight, + $targetWidth, + $targetHeight, + $expectedWidth, + $expectedHeight + ) { $img = new CImageResizer(/*'logger'*/); //$img = new CImageResizer('logger'); diff --git a/test/CImageResizerByDensityPixelRatioTest.php b/test/CImageResizerByDensityPixelRatioTest.php index 7552b6f..dd4d164 100644 --- a/test/CImageResizerByDensityPixelRatioTest.php +++ b/test/CImageResizerByDensityPixelRatioTest.php @@ -50,8 +50,15 @@ class CImageResizerByDevicePixelRatioTest extends \PHPUnit_Framework_TestCase * * @return void */ - public function testResize1($dpr, $srcWidth, $srcHeight, $targetWidth, $targetHeight, $expectedWidth, $expectedHeight) - { + public function testResize1( + $dpr, + $srcWidth, + $srcHeight, + $targetWidth, + $targetHeight, + $expectedWidth, + $expectedHeight + ) { $img = new CImageResizer(/*'logger'*/); //$img = new CImageResizer('logger'); diff --git a/test/CImageResizerStrategyCropToFitTest.php b/test/CImageResizerStrategyCropToFitTest.php index b9c9efb..bec70a3 100644 --- a/test/CImageResizerStrategyCropToFitTest.php +++ b/test/CImageResizerStrategyCropToFitTest.php @@ -107,7 +107,7 @@ class CImageResizerStrategyCropToFitTest extends \PHPUnit_Framework_TestCase */ public function testResize2($sw, $sh, $tw, $th, $cx, $cy, $cw, $ch, $dx, $dy, $dw, $dh) { - $img = new CImageResizer(/*'logger'/**/); + $img = new CImageResizer(/*'logger'/**/); $img->setSource($sw, $sh) ->setBaseWidthHeight($tw, $th) diff --git a/test/CImageResizerStrategyFillToFitTest.php b/test/CImageResizerStrategyFillToFitTest.php index d2d72ed..51d056c 100644 --- a/test/CImageResizerStrategyFillToFitTest.php +++ b/test/CImageResizerStrategyFillToFitTest.php @@ -62,7 +62,6 @@ class CImageResizerStrategyFillToFitTest extends \PHPUnit_Framework_TestCase $this->assertEquals($dy, $img->getDestinationY(), "DestinationY not correct."); $this->assertEquals($dw, $img->getDestinationWidth(), "DestinationWidth not correct."); $this->assertEquals($dh, $img->getDestinationHeight(), "DestinationHeight not correct."); - } @@ -116,6 +115,5 @@ class CImageResizerStrategyFillToFitTest extends \PHPUnit_Framework_TestCase $this->assertEquals($dy, $img->getDestinationY(), "DestinationY not correct."); $this->assertEquals($dw, $img->getDestinationWidth(), "DestinationWidth not correct."); $this->assertEquals($dh, $img->getDestinationHeight(), "DestinationHeight not correct."); - } } diff --git a/test/CImageResizerStrategyStretchTest.php b/test/CImageResizerStrategyStretchTest.php index 0a54796..ff28cfe 100644 --- a/test/CImageResizerStrategyStretchTest.php +++ b/test/CImageResizerStrategyStretchTest.php @@ -53,6 +53,5 @@ class CImageResizerStrategyStretchTest extends \PHPUnit_Framework_TestCase $this->assertEquals($tw, $img->getTargetWidth(), "Target width not correct."); $this->assertEquals($th, $img->getTargetHeight(), "Target height not correct."); - } } diff --git a/test/CImgTest.php b/test/CImgTest.php new file mode 100644 index 0000000..7f68526 --- /dev/null +++ b/test/CImgTest.php @@ -0,0 +1,54 @@ + "car.png", + "json" => true, + "rotate" => 90, + ]], + ]; + } + + + + /** + * Test + * + * @-preserveGlobalState disabled + * @runInSeparateProcess + * + * @dataProvider providerQueryString + * + * @return void + */ + public function testResize($query) + { + //$_GET = $query; + + #ob_start(); + //$res = require "webroot/img.php"; + #$res = ob_get_clean(); + + //echo "MOPED $res"; + } +} diff --git a/webroot/img.php b/webroot/img.php index 107a7c5..c26bc4d 100644 --- a/webroot/img.php +++ b/webroot/img.php @@ -8,6 +8,22 @@ * */ +/** + * Custom exception handler. + */ +set_exception_handler(function ($exception) { + errorPage( + "

img.php: Uncaught exception:

" + . $exception->getMessage() + . "

"
+        . $exception->getTraceAsString()
+        . "
", + 500 + ); +}); + + + /** * Get configuration options from file, if the file exists, else use $config * if its defined or create an empty $config. @@ -198,7 +214,7 @@ verbose("referer host = $refererHost"); /** * Create the class for the image. */ -$CImage = getConfig('CImage', 'CImage'); +$CImage = getConfig('CImage', '\Mos\CImage\CImage'); $img = new $CImage(); $img->setVerbose($verbose || $verboseFile); @@ -207,7 +223,7 @@ $img->setVerbose($verbose || $verboseFile); /** * Get the cachepath from config. */ -$CCache = getConfig('CCache', 'CCache'); +$CCache = getConfig('CCache', '\Mos\CImage\CCache'); $cachePath = getConfig('cache_path', __DIR__ . '/../cache/'); $cache = new $CCache(); $cache->setDir($cachePath); @@ -229,7 +245,7 @@ verbose("use cache = $useCache"); $fastTrackCache = "fasttrack"; $allowFastTrackCache = getConfig('fast_track_allow', false); -$CFastTrackCache = getConfig('CFastTrackCache', 'CFastTrackCache'); +$CFastTrackCache = getConfig('CFastTrackCache', '\Mos\CImage\CFastTrackCache'); $ftc = new $CFastTrackCache(); $ftc->setCacheDir($cache->getPathToSubdir($fastTrackCache)) ->enable($allowFastTrackCache) diff --git a/webroot/img_config.php b/webroot/img_config.php index d947e63..9317d9f 100644 --- a/webroot/img_config.php +++ b/webroot/img_config.php @@ -91,13 +91,13 @@ return [ * the codebase. * * Default values: - * CImage: CImage - * CCache: CCache - * CFastTrackCache: CFastTrackCache + * CImage: \Mos\CImage\CImage + * CCache: \Mos\CImage\CCache + * CFastTrackCache: \Mos\CImage\CFastTrackCache */ - //'CImage' => 'CImage', - //'CCache' => 'CCache', - //'CFastTrackCache' => 'CFastTrackCache', + //'CImage' => '\Mos\CImage\CImage', + //'CCache' => '\Mos\CImage\CCache', + //'CFastTrackCache' => '\Mos\CImage\CFastTrackCache',