Merge branch 'develop' into testing/views

This commit is contained in:
Master Yoda 2018-06-05 12:50:25 -07:00
commit 73448576e5
No known key found for this signature in database
GPG Key ID: CED549230775AD5B
25 changed files with 682 additions and 83 deletions

View File

@ -38,6 +38,8 @@ class ContentSecurityPolicy extends BaseConfig
public $mediaSrc = null;
public $objectSrc = null;
public $manifestSrc = null;
public $pluginTypes = null;

View File

@ -10,4 +10,14 @@ class FileException extends \RuntimeException implements ExceptionInterface
return new static(lang('Files.cannotMove', [$from, $to, $error]));
}
public static function forInvalidFilename(string $to = null)
{
return new self(lang('Files.invalidFilename', [$to]));
}
public static function forCopyError(string $to = null)
{
return new self(lang('Files.cannotCopy', [$to]));
}
}

View File

@ -140,6 +140,12 @@ class ContentSecurityPolicy
* @var array
*/
protected $styleSrc = [];
/**
* Used for security enforcement
* @var array
*/
protected $manifestSrc = [];
/**
* Used for security enforcement
@ -432,6 +438,26 @@ class ContentSecurityPolicy
return $this;
}
//--------------------------------------------------------------------
/**
* Adds a new valid endpoint for manifest sources. Can be either
* a URI class or simple string.
*
* @see https://www.w3.org/TR/CSP/#directive-manifest-src
*
* @param $uri
* @param bool $reportOnly
*
* @return $this
*/
public function addManifestSrc($uri, bool $reportOnly = false)
{
$this->addOption($uri, 'manifestSrc', $reportOnly);
return $this;
}
//--------------------------------------------------------------------
@ -688,6 +714,7 @@ class ContentSecurityPolicy
'plugin-types' => 'pluginTypes',
'script-src' => 'scriptSrc',
'style-src' => 'styleSrc',
'manifest-src' => 'manifestSrc',
'sandbox' => 'sandbox',
'report-uri' => 'reportURI'
];

View File

@ -52,9 +52,9 @@ abstract class BaseHandler implements ImageHandlerInterface
* d
* @var \CodeIgniter\Images\Image
*/
protected $image;
protected $width;
protected $height;
protected $image = null;
protected $width = 0;
protected $height = 0;
protected $filePermissions = 0644;
protected $xAxis = 0;
protected $yAxis = 0;
@ -112,13 +112,41 @@ abstract class BaseHandler implements ImageHandlerInterface
$this->image = new Image($path, true);
$this->image->getProperties();
$this->image->getProperties(false);
$this->width = $this->image->origWidth;
$this->height = $this->image->origHeight;
return $this;
}
//--------------------------------------------------------------------
/**
* Make the image resource object if needed
*/
protected function ensureResource()
{
if ($this->resource == null)
{
$path = $this->image->getPathname();
// if valid image type, make corresponding image resource
switch ($this->image->imageType)
{
case IMAGETYPE_GIF:
$this->resource = imagecreatefromgif($path);
break;
case IMAGETYPE_JPEG:
$this->resource = imagecreatefromjpeg($path);
break;
case IMAGETYPE_PNG:
$this->resource = imagecreatefrompng($path);
break;
}
}
}
//--------------------------------------------------------------------
/**
* Returns the image instance.
*
@ -140,6 +168,7 @@ abstract class BaseHandler implements ImageHandlerInterface
*/
public function getResource()
{
$this->ensureResource();
return $this->resource;
}
@ -231,16 +260,15 @@ abstract class BaseHandler implements ImageHandlerInterface
throw ImageException::forMissingAngle();
}
// cast angle as an int, for our use
$angle = (int) $angle;
// Reassign the width and height
if ($angle === 90 || $angle === 270)
{
$this->width = $this->image->origHeight;
$this->height = $this->image->origWidth;
}
else
{
$this->width = $this->image->origWidth;
$this->height = $this->image->origHeight;
$temp = $this->height;
$this->width = $this->height;
$this->height = $temp;
}
// Call the Handler-specific version.
@ -303,13 +331,13 @@ abstract class BaseHandler implements ImageHandlerInterface
*
* @return $this
*/
public function flip(string $dir)
public function flip(string $dir = 'vertical')
{
$dir = strtolower($dir);
if ($dir !== 'vertical' && $dir !== 'horizontal')
{
throw new ImageException(lang('images.invalidDirection'));
throw ImageException::forInvalidDirection($dir);
}
return $this->_flip($dir);
@ -347,7 +375,7 @@ abstract class BaseHandler implements ImageHandlerInterface
* @param string $text
* @param array $options
*
* @return BaseHandler
* @return $this
*/
public function text(string $text, array $options = [])
{
@ -437,12 +465,9 @@ abstract class BaseHandler implements ImageHandlerInterface
{
return null;
}
throw ImageException::forEXIFUnsupported();
}
$exif = exif_read_data($this->image->getPathname());
if ( ! is_null($key) && is_array($exif))
{
$exif = array_key_exists($key, $exif) ? $exif[$key] : false;
@ -662,7 +687,12 @@ abstract class BaseHandler implements ImageHandlerInterface
*/
protected function reproportion()
{
if (($this->width === 0 && $this->height === 0) || $this->image->origWidth === 0 || $this->image->origHeight === 0 || ( ! ctype_digit((string) $this->width) && ! ctype_digit((string) $this->height)) || ! ctype_digit((string) $this->image->origWidth) || ! ctype_digit((string) $this->image->origHeight)
if (($this->width === 0 && $this->height === 0) ||
$this->image->origWidth === 0 ||
$this->image->origHeight === 0 ||
( ! ctype_digit((string) $this->width) && ! ctype_digit((string) $this->height)) ||
! ctype_digit((string) $this->image->origWidth) ||
! ctype_digit((string) $this->image->origHeight)
)
{
return;
@ -700,4 +730,16 @@ abstract class BaseHandler implements ImageHandlerInterface
}
//--------------------------------------------------------------------
// accessor for testing; not part of interface
public function getWidth()
{
return ($this->resource != null) ? $this->_getWidth() : $this->width;
}
// accessor for testing; not part of interface
public function getHeight()
{
return ($this->resource != null) ? $this->_getHeight() : $this->height;
}
}

View File

@ -42,21 +42,17 @@ class GDHandler extends BaseHandler
public $version;
/**
* Stores image resource in memory.
*
* @var
*/
protected $resource;
public function __construct($config = null)
{
parent::__construct($config);
// We should never see this, so can't test it
// @codeCoverageIgnoreStart
if ( ! extension_loaded('gd'))
{
throw ImageException::forMissingExtension('GD');
}
// @codeCoverageIgnoreEnd
}
//--------------------------------------------------------------------
@ -72,10 +68,7 @@ class GDHandler extends BaseHandler
protected function _rotate(int $angle)
{
// Create the image handle
if ( ! ($srcImg = $this->createImage()))
{
return false;
}
$srcImg = $this->createImage();
// Set the background color
// This won't work with transparent PNG files so we are
@ -85,7 +78,7 @@ class GDHandler extends BaseHandler
$white = imagecolorallocate($srcImg, 255, 255, 255);
// Rotate it!
$destImg = imagerotate($this->resource, $angle, $white);
$destImg = imagerotate($srcImg, $angle, $white);
// Kill the file handles
imagedestroy($srcImg);
@ -106,12 +99,9 @@ class GDHandler extends BaseHandler
*
* @return $this
*/
public function _flatten(int $red = 255, int $green = 255, int $blue = 255) {
if ( ! ($src = $this->createImage()))
{
return false;
}
public function _flatten(int $red = 255, int $green = 255, int $blue = 255)
{
$srcImg = $this->createImage();
if (function_exists('imagecreatetruecolor'))
{
@ -128,15 +118,14 @@ class GDHandler extends BaseHandler
$matte = imagecolorallocate($dest, $red, $green, $blue);
imagefilledrectangle($dest, 0, 0, $this->width, $this->height, $matte);
imagecopy($dest, $src, 0, 0, 0, 0, $this->width, $this->height);
imagecopy($dest, $srcImg, 0, 0, 0, 0, $this->width, $this->height);
// Kill the file handles
imagedestroy($src);
imagedestroy($srcImg);
$this->resource = $dest;
return $this;
}
//--------------------------------------------------------------------
@ -157,7 +146,7 @@ class GDHandler extends BaseHandler
if ($direction === 'horizontal')
{
for ($i = 0; $i < $height; $i ++ )
for ($i = 0; $i < $height; $i ++)
{
$left = 0;
$right = $width - 1;
@ -177,7 +166,7 @@ class GDHandler extends BaseHandler
}
else
{
for ($i = 0; $i < $width; $i ++ )
for ($i = 0; $i < $width; $i ++)
{
$top = 0;
$bottom = $height - 1;
@ -422,7 +411,7 @@ class GDHandler extends BaseHandler
return imagecreatefrompng($path);
default:
throw ImageException::forInvalidImageCreate();
throw ImageException::forInvalidImageCreate('Ima');
}
}
@ -560,4 +549,15 @@ class GDHandler extends BaseHandler
}
//--------------------------------------------------------------------
public function _getWidth()
{
return imagesx($this->resource);
}
public function _getHeight()
{
return imagesy($this->resource);
}
}

View File

@ -44,6 +44,10 @@ use CodeIgniter\Images\Image;
* To make this library as compatible as possible with the broadest
* number of installations, we do not use the Imagick extension,
* but simply use the command line version.
*
* hmm - the width & height accessors at the end use the imagick extension.
*
* FIXME - This needs conversion & unit testing, to use the imagick extension
*
* @package CodeIgniter\Images\Handlers
*/
@ -61,6 +65,13 @@ class ImageMagickHandler extends BaseHandler
//--------------------------------------------------------------------
public function __construct($config = null)
{
parent::__construct($config);
}
//--------------------------------------------------------------------
/**
* Handles the actual resizing of the image.
*
@ -76,7 +87,8 @@ class ImageMagickHandler extends BaseHandler
//todo FIX THIS HANDLER PROPERLY
$escape = "\\";
if (strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN') {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
{
$escape = "";
}
@ -141,9 +153,10 @@ class ImageMagickHandler extends BaseHandler
*
* @return $this
*/
public function _flatten(int $red = 255, int $green = 255, int $blue = 255){
public function _flatten(int $red = 255, int $green = 255, int $blue = 255)
{
$flatten = "-background RGB({$red},{$green},{$blue}) -flatten";
$flatten = "-background RGB({$red},{$green},{$blue}) -flatten";
$source = ! empty($this->resource) ? $this->resource : $this->image->getPathname();
$destination = $this->getResourcePath();
@ -408,4 +421,18 @@ class ImageMagickHandler extends BaseHandler
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
public function _getWidth()
{
return imagesx($this->resource);
}
public function _getHeight()
{
return imagesy($this->resource);
}
}

View File

@ -107,7 +107,7 @@ class Image extends File
if ( ! copy($this->getPathname(), "{$targetPath}{$targetName}"))
{
throw ImageException::forCopyError();
throw ImageException::forCopyError($targetPath);
}
chmod("{$targetPath}/{$targetName}", $perms);
@ -132,6 +132,7 @@ class Image extends File
$vals = getimagesize($path);
$types = [1 => 'gif', 2 => 'jpeg', 3 => 'png'];
$mime = 'image/' . ($types[$vals[2]] ?? 'jpg');
if ($return === true)

View File

@ -44,8 +44,9 @@ interface ImageHandlerInterface
* @param int $width
* @param int $height
* @param bool $maintainRatio If true, will get the closest match possible while keeping aspect ratio true.
* @param string $masterDim
*/
public function resize(int $width, int $height, bool $maintainRatio = false);
public function resize(int $width, int $height, bool $maintainRatio = false, string $masterDim = 'auto');
//--------------------------------------------------------------------
@ -58,10 +59,12 @@ interface ImageHandlerInterface
* @param int|null $height
* @param int|null $x X-axis coord to start cropping from the left of image
* @param int|null $y Y-axis coord to start cropping from the top of image
* @param bool $maintainRatio
* @param string $masterDim
*
* @return mixed
*/
public function crop(int $width = null, int $height = null, int $x = null, int $y = null);
public function crop(int $width = null, int $height = null, int $x = null, int $y = null, bool $maintainRatio = false, string $masterDim = 'auto');
//--------------------------------------------------------------------
@ -110,6 +113,17 @@ interface ImageHandlerInterface
//--------------------------------------------------------------------
/**
* Flip an image horizontally or vertically
*
* @param string $dir Direction to flip, either 'vertical' or 'horizontal'
*
* @return mixed
*/
public function flip(string $dir = 'vertical');
//--------------------------------------------------------------------
/**
* Combine cropping and resizing into a single command.
*
@ -133,4 +147,42 @@ interface ImageHandlerInterface
public function fit(int $width, int $height, string $position);
//--------------------------------------------------------------------
/**
* Overlays a string of text over the image.
*
* Valid options:
*
* - color Text Color (hex number)
* - shadowColor Color of the shadow (hex number)
* - hAlign Horizontal alignment: left, center, right
* - vAlign Vertical alignment: top, middle, bottom
* - hOffset
* - vOffset
* - fontPath
* - fontSize
* - shadowOffset
*
* @param string $text
* @param array $options
*
* @return $this
*/
public function text(string $text, array $options = []);
//--------------------------------------------------------------------
/**
* Saves any changes that have been made to file.
*
* Example:
* $image->resize(100, 200, true)
* ->save($target);
*
* @param string $target
* @param int $quality
*
* @return mixed
*/
public function save(string $target = null, int $quality = 90);
}

View File

@ -1,5 +1,4 @@
<?php
/**
* Files language strings.
*
@ -14,6 +13,8 @@
* @codeCoverageIgnore
*/
return [
'fileNotFound' => 'File not found: {0}',
'cannotMove' => 'Could not move file {0} to {1} ({2})',
'fileNotFound' => 'File not found: {0}',
'cannotMove' => 'Could not move file {0} to {1} ({2})',
'invalidFilename' => 'Target filename missing or invalid: {0}',
'cannotCopy' => 'Could not copy to {0} - make sure the folder is writeable',
];

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,96 @@
<?php namespace CodeIgniter\Images;
use CodeIgniter\Images\Exceptions\ImageException;
use CodeIgniter\Files\Exceptions\FileException;
use CodeIgniter\Config\Services;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
/**
* Test the common image processing functionality.
*
* Note: some of the underlying PHP functions do not play nicely
* with vfsStream, so the support files are used directly for
* most work, and the virtual file system will be used for
* testing saving only.
*/
class BaseHandlerTest extends \CIUnitTestCase
{
public function setUp()
{
if ( ! extension_loaded('gd'))
{
$this->markTestSkipped('The GD extension is not available.');
return;
}
// create virtual file system
$this->root = vfsStream::setup();
// copy our support files
$this->origin = SUPPORTPATH . 'Images/';
vfsStream::copyFromFileSystem($this->origin, $this->root);
// make subfolders
$structure = ['work' => [], 'wontwork' => []];
vfsStream::create($structure);
// with one of them read only
$wont = $this->root->getChild('wontwork')->chmod(0400);
// for VFS tests
$this->start = $this->root->url() . '/';
$this->path = $this->start . 'ci-logo.png';
}
//--------------------------------------------------------------------
public function testNew()
{
$handler = Services::image('gd', null, false);
$this->assertTrue($handler instanceof Handlers\BaseHandler);
}
public function testWithFile()
{
$path = $this->origin . 'ci-logo.png';
$handler = Services::image('gd', null, false);
$handler->withFile($path);
$image = $handler->getFile();
$this->assertTrue($image instanceof Image);
$this->assertEquals(155, $image->origWidth);
$this->assertEquals($path, $image->getPathname());
}
public function testMissingFile()
{
$this->expectException(\CodeIgniter\Files\Exceptions\FileNotFoundException::class);
$handler = Services::image('gd', null, false);
$handler->withFile($this->start . 'No_such_file.jpg');
}
public function testFileTypes()
{
$handler = Services::image('gd', null, false);
$handler->withFile($this->start . 'ci-logo.png');
$image = $handler->getFile();
$this->assertTrue($image instanceof Image);
$handler->withFile($this->start . 'ci-logo.jpeg');
$image = $handler->getFile();
$this->assertTrue($image instanceof Image);
$handler->withFile($this->start . 'ci-logo.gif');
$image = $handler->getFile();
$this->assertTrue($image instanceof Image);
}
//--------------------------------------------------------------------
// Something handled by our Image
public function testImageHandled()
{
$handler = Services::image('gd', null, false);
$handler->withFile($this->path);
$this->assertEquals($this->path, $handler->getPathname());
}
}

View File

@ -1,14 +1,326 @@
<?php namespace CodeIgniter\Images;
use CodeIgniter\Images\BaseHandler;
use CodeIgniter\Images\Exceptions\ImageException;
use CodeIgniter\Files\Exceptions\FileException;
use CodeIgniter\Config\Services;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
use DirectoryIterator;
/**
* Unit testing for the GD image handler.
* It is impractical to programmatically inspect the results of the
* different transformations, so we have to rely on the underlying package.
* We can make sure that we can call it without blowing up,
* and we can make sure the code coverage is good.
*
* Was unable to test fontPath & related logic.
*/
class GDHandlerTest extends \CIUnitTestCase
{
protected $path = 'tests/_support/ci-logo.png';
public function testCanReachImageMethods()
public function setUp()
{
$image = new Image(ROOTPATH.$this->path);
if ( ! extension_loaded('gd'))
{
$this->markTestSkipped('The GD extension is not available.');
return;
}
$this->assertInternalType('array', $image->getProperties(true));
// create virtual file system
$this->root = vfsStream::setup();
// copy our support files
$this->origin = SUPPORTPATH . 'Images/';
// make subfolders
$structure = ['work' => [], 'wontwork' => []];
vfsStream::create($structure);
// with one of them read only
$wont = $this->root->getChild('wontwork')->chmod(0400);
$this->start = $this->root->url() . '/';
$this->path = $this->origin . 'ci-logo.png';
$this->handler = Services::image('gd', null, false);
}
public function testGetVersion()
{
$version = $this->handler->getVersion();
// make sure that the call worked
$this->assertNotFalse($version);
// we should have a numeric version, with 3 digits
$this->assertGreaterThan(100, $version);
$this->assertLessThan(999, $version);
}
public function testImageProperties()
{
$this->handler->withFile($this->path);
$file = $this->handler->getFile();
$props = $file->getProperties(true);
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(155, $props['width']);
$this->assertEquals(155, $file->origWidth);
$this->assertEquals(200, $this->handler->getHeight());
$this->assertEquals(200, $props['height']);
$this->assertEquals(200, $file->origHeight);
$this->assertEquals('width="155" height="200"', $props['size_str']);
}
public function testImageTypeProperties()
{
$this->handler->withFile($this->path);
$file = $this->handler->getFile();
$props = $file->getProperties(true);
$this->assertEquals(IMAGETYPE_PNG, $props['image_type']);
$this->assertEquals('image/png', $props['mime_type']);
}
//--------------------------------------------------------------------
public function testResizeIgnored()
{
$this->handler->withFile($this->path);
$this->handler->resize(155, 200); // 155x200 result
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
public function testResizeAbsolute()
{
$this->handler->withFile($this->path);
$this->handler->resize(123, 456, false); // 123x456 result
$this->assertEquals(123, $this->handler->getWidth());
$this->assertEquals(456, $this->handler->getHeight());
}
public function testResizeAspect()
{
$this->handler->withFile($this->path);
$this->handler->resize(123, 456, true); // 123x159 result
$this->assertEquals(123, $this->handler->getWidth());
$this->assertEquals(159, $this->handler->getHeight());
}
public function testResizeAspectWidth()
{
$this->handler->withFile($this->path);
$this->handler->resize(123, 0, true); // 123x159 result
$this->assertEquals(123, $this->handler->getWidth());
$this->assertEquals(159, $this->handler->getHeight());
}
public function testResizeAspectHeight()
{
$this->handler->withFile($this->path);
$this->handler->resize(0, 456, true); // 354x456 result
$this->assertEquals(354, $this->handler->getWidth());
$this->assertEquals(456, $this->handler->getHeight());
}
//--------------------------------------------------------------------
public function testCropTopLeft()
{
$this->handler->withFile($this->path);
$this->handler->crop(100, 100); // 100x100 result
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(100, $this->handler->getHeight());
}
public function testCropMiddle()
{
$this->handler->withFile($this->path);
$this->handler->crop(100, 100, 50, 50, false); // 100x100 result
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(100, $this->handler->getHeight());
}
public function testCropMiddlePreserved()
{
$this->handler->withFile($this->path);
$this->handler->crop(100, 100, 50, 50, true); // 78x100 result
$this->assertEquals(78, $this->handler->getWidth());
$this->assertEquals(100, $this->handler->getHeight());
}
public function testCropTopLeftPreserveAspect()
{
$this->handler->withFile($this->path);
$this->handler->crop(100, 100); // 100x100 result
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(100, $this->handler->getHeight());
}
public function testCropNothing()
{
$this->handler->withFile($this->path);
$this->handler->crop(155, 200); // 155x200 result
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
public function testCropOutOfBounds()
{
$this->handler->withFile($this->path);
$this->handler->crop(100, 100, 100); // 55x100 result in 100x100
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(100, $this->handler->getHeight());
}
//--------------------------------------------------------------------
public function testRotate()
{
$this->handler->withFile($this->path); // 155x200
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
// first rotation
$this->handler->rotate(90); // 200x155
$this->assertEquals(200, $this->handler->getWidth());
// check image size again after another rotation
$this->handler->rotate(180); // 200x155
$this->assertEquals(200, $this->handler->getWidth());
}
public function testRotateBadAngle()
{
$this->handler->withFile($this->path);
$this->expectException(ImageException::class);
$this->handler->rotate(77);
}
//--------------------------------------------------------------------
public function testFlatten()
{
$this->handler->withFile($this->path);
$this->handler->flatten();
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
//--------------------------------------------------------------------
public function testFlip()
{
$this->handler->withFile($this->path);
$this->handler->flip();
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
public function testHorizontal()
{
$this->handler->withFile($this->path);
$this->handler->flip('horizontal');
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
public function testFlipVertical()
{
$this->handler->withFile($this->path);
$this->handler->flip('vertical');
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
public function testFlipUnknown()
{
$this->handler->withFile($this->path);
$this->expectException(ImageException::class);
$this->handler->flip('bogus');
}
//--------------------------------------------------------------------
public function testFit()
{
$this->handler->withFile($this->path);
$this->handler->fit(100, 100);
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(100, $this->handler->getHeight());
}
public function testFitTaller()
{
$this->handler->withFile($this->path);
$this->handler->fit(100, 400);
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(400, $this->handler->getHeight());
}
public function testFitAutoHeight()
{
$this->handler->withFile($this->path);
$this->handler->fit(100);
$this->assertEquals(100, $this->handler->getWidth());
$this->assertEquals(129, $this->handler->getHeight());
}
public function testFitPositions()
{
$choices = ['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'];
$this->handler->withFile($this->path);
foreach ($choices as $position)
{
$this->handler->fit(100, 100, $position);
$this->assertEquals(100, $this->handler->getWidth(), 'Position ' . $position . ' failed');
$this->assertEquals(100, $this->handler->getHeight(), 'Position ' . $position . ' failed');
}
}
//--------------------------------------------------------------------
public function testText()
{
$this->handler->withFile($this->path);
$this->handler->text('vertical', ['hAlign' => 'right', 'vAlign' => 'bottom']);
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
//--------------------------------------------------------------------
public function testMoreText()
{
$this->handler->withFile($this->path);
$this->handler->text('vertical', ['vAlign' => 'middle', 'withShadow' => 'sure', 'shadowOffset' => 3]);
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
//--------------------------------------------------------------------
public function testImageCreation()
{
foreach (['gif', 'jpeg', 'png'] as $type)
{
$this->handler->withFile($this->origin . 'ci-logo.' . $type);
$this->handler->text('vertical');
$this->assertEquals(155, $this->handler->getWidth());
$this->assertEquals(200, $this->handler->getHeight());
}
}
//--------------------------------------------------------------------
public function testImageSave()
{
foreach (['gif', 'jpeg', 'png'] as $type)
{
$this->handler->withFile($this->origin . 'ci-logo.' . $type);
$this->handler->getResource(); // make sure resource is loaded
$this->handler->save($this->start . 'work/ci-logo.' . $type);
$this->assertTrue($this->root->hasChild('work/ci-logo.' . $type));
}
}
}

View File

@ -1,56 +1,84 @@
<?php namespace CodeIgniter\Images;
use CodeIgniter\Images\Exceptions\ImageException;
use CodeIgniter\Files\Exceptions\FileException;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
class ImageTest extends \CIUnitTestCase
{
protected $path = 'tests/_support/ci-logo.png';
public function setup()
{
// create virtual file system
$this->root = vfsStream::setup();
// copy our support files
$this->origin = '_support/Images/';
vfsStream::copyFromFileSystem(TESTPATH . $this->origin, $this->root);
// make subfolders
$structure = ['work' => [], 'wontwork' => []];
vfsStream::create($structure);
// with one of them read only
$wont = $this->root->getChild('wontwork')->chmod(0400);
$this->start = $this->root->url() . '/';
$this->image = new Image($this->start . 'ci-logo.png');
}
public function testBasicPropertiesInherited()
{
$image = new Image(ROOTPATH.$this->path);
$this->assertEquals('ci-logo.png', $image->getFilename());
$this->assertEquals(ROOTPATH.$this->path, $image->getPathname());
$this->assertEquals(ROOTPATH.'tests/_support', $image->getPath());
$this->assertEquals('ci-logo.png', $image->getBasename());
$this->assertEquals('ci-logo.png', $this->image->getFilename());
$this->assertEquals($this->start . 'ci-logo.png', $this->image->getPathname());
$this->assertEquals($this->root->url(), $this->image->getPath());
$this->assertEquals('ci-logo.png', $this->image->getBasename());
}
public function testGetProperties()
{
$image = new Image(ROOTPATH.$this->path);
$expected = [
'width' => 155,
'height' => 200,
'width' => 155,
'height' => 200,
'image_type' => IMAGETYPE_PNG,
'size_str' => 'width="155" height="200"',
'mime_type' => "image/png",
'size_str' => 'width="155" height="200"',
'mime_type' => "image/png",
];
$this->assertEquals($expected, $image->getProperties(true));
$this->assertEquals($expected, $this->image->getProperties(true));
}
public function testCanCopyDefaultName()
public function testExtractProperties()
{
$image = new Image(ROOTPATH.$this->path);
// extract properties from the image
$this->assertTrue($this->image->getProperties(false));
$image->copy(WRITEPATH);
$this->assertFileExists(WRITEPATH.'ci-logo.png');
unlink(WRITEPATH.'ci-logo.png');
$this->assertEquals(155, $this->image->origWidth);
$this->assertEquals(200, $this->image->origHeight);
$this->assertEquals(IMAGETYPE_PNG, $this->image->imageType);
$this->assertEquals('width="155" height="200"', $this->image->sizeStr);
$this->assertEquals("image/png", $this->image->mime);
}
public function testCanCopyNewName()
public function testCopyDefaultName()
{
$image = new Image(ROOTPATH.$this->path);
$targetPath = $this->start . 'work';
$this->image->copy($targetPath);
$this->assertTrue($this->root->hasChild('work/ci-logo.png'));
}
$image->copy(WRITEPATH, 'new-logo.png');
public function testCopyNewName()
{
$this->image->copy($this->root->url(), 'new-logo.png');
$this->assertTrue($this->root->hasChild('new-logo.png'));
}
$this->assertFileExists(WRITEPATH.'new-logo.png');
unlink(WRITEPATH.'new-logo.png');
public function testCopyNowhere()
{
$this->expectException(ImageException::class);
$targetPath = $this->start . 'work';
$this->image->copy($targetPath, '');
}
}

View File

@ -179,6 +179,7 @@ class holds a number of methods that map pretty clearly to the appropriate heade
$response->CSP->addFrameAncestor('none', $reportOnly);
$response->CSP->addImageSrc('cdn.example.com', $reportOnly);
$response->CSP->addMediaSrc('cdn.example.com', $reportOnly);
$response->CSP->addManifestSrc('cdn.example.com', $reportOnly);
$response->CSP->addObjectSrc('cdn.example.com', $reportOnly);
$response->CSP->addPluginType('application/pdf', $reportOnly);
$response->CSP->addScriptSrc('scripts.example.com', $reportOnly);