Skip to content

Commit

Permalink
Add image formats to Faker\Provider\Image (#473)
Browse files Browse the repository at this point in the history
* Added image formats to `Faker\Provider\Image`

* Wrote unit tests for image formats in `Image`

* Renamed test

* Used Image constants, added test for downloaded image

* Fixed `php-cs-fixer` issues

Co-authored-by: Caleb White <[email protected]>
  • Loading branch information
calebdw and Caleb White authored May 11, 2022
1 parent 4e206f8 commit f66a262
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 21 deletions.
42 changes: 37 additions & 5 deletions src/Faker/Provider/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class Image extends Base
*/
public const BASE_URL = 'https://via.placeholder.com';

public const FORMAT_JPG = 'jpg';
public const FORMAT_JPEG = 'jpeg';
public const FORMAT_PNG = 'png';

/**
* @var array
*
Expand All @@ -35,6 +39,7 @@ class Image extends Base
* @param bool $randomize
* @param string|null $word
* @param bool $gray
* @param string $format
*
* @return string
*/
Expand All @@ -44,9 +49,21 @@ public static function imageUrl(
$category = null,
$randomize = true,
$word = null,
$gray = false
$gray = false,
$format = 'png'
) {
$size = sprintf('%dx%d.png', $width, $height);
// Validate image format
$imageFormats = static::getFormats();

if (!in_array(strtolower($format), $imageFormats, true)) {
throw new \InvalidArgumentException(sprintf(
'Invalid image format "%s". Allowable formats are: %s',
$format,
implode(', ', $imageFormats)
));
}

$size = sprintf('%dx%d.%s', $width, $height, $format);

$imageParts = [];

Expand Down Expand Up @@ -90,7 +107,8 @@ public static function image(
$fullPath = true,
$randomize = true,
$word = null,
$gray = false
$gray = false,
$format = 'png'
) {
$dir = null === $dir ? sys_get_temp_dir() : $dir; // GNU/Linux / OS X / Windows compatible
// Validate directory path
Expand All @@ -101,10 +119,10 @@ public static function image(
// Generate a random filename. Use the server address so that a file
// generated at the same time on a different server won't have a collision.
$name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));
$filename = $name . '.png';
$filename = sprintf('%s.%s', $name, $format);
$filepath = $dir . DIRECTORY_SEPARATOR . $filename;

$url = static::imageUrl($width, $height, $category, $randomize, $word, $gray);
$url = static::imageUrl($width, $height, $category, $randomize, $word, $gray, $format);

// save file
if (function_exists('curl_exec')) {
Expand Down Expand Up @@ -136,4 +154,18 @@ public static function image(

return $fullPath ? $filepath : $filename;
}

public static function getFormats(): array
{
return array_keys(static::getFormatConstants());
}

public static function getFormatConstants(): array
{
return [
static::FORMAT_JPG => constant('IMAGETYPE_JPEG'),
static::FORMAT_JPEG => constant('IMAGETYPE_JPEG'),
static::FORMAT_PNG => constant('IMAGETYPE_PNG'),
];
}
}
105 changes: 89 additions & 16 deletions test/Faker/Provider/ImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,35 +85,108 @@ public function testImageUrlAddsARandomGetParameterByDefault()
self::assertMatchesRegularExpression('#\w*#', $splitUrl[1]);
}

public function testDownloadWithDefaults()
public function testImageUrlThrowsExceptionOnInvalidImageFormat()
{
$curlPing = curl_init(Image::BASE_URL);
curl_setopt($curlPing, CURLOPT_TIMEOUT, 5);
curl_setopt($curlPing, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curlPing, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlPing, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($curlPing);
$httpCode = curl_getinfo($curlPing, CURLINFO_HTTP_CODE);
curl_close($curlPing);
$this->expectException(\InvalidArgumentException::class);
Image::imageUrl(
800,
400,
'nature',
false,
'Faker',
true,
'foo'
);
}

if ($httpCode < 200 | $httpCode > 300) {
self::markTestSkipped('Placeholder.com is offline, skipping image download');
public function testImageUrlAcceptsDifferentImageFormats()
{
foreach (Image::getFormats() as $format) {
$imageUrl = Image::imageUrl(
800,
400,
'nature',
false,
'Faker',
true,
$format
);

self::assertMatchesRegularExpression(
"#^https://via.placeholder.com/800x400.{$format}/CCCCCC\?text=nature\+Faker#",
$imageUrl
);
}
}

public function testDownloadWithDefaults()
{
self::checkUrlConnection(Image::BASE_URL);

$file = Image::image(sys_get_temp_dir());
self::assertFileExists($file);

self::checkImageProperties($file, 640, 480, 'png');
}

public function testDownloadWithDifferentImageFormats()
{
self::checkUrlConnection(Image::BASE_URL);

foreach (Image::getFormats() as $format) {
$width = 800;
$height = 400;
$file = Image::image(
sys_get_temp_dir(),
$width,
$height,
'nature',
true,
false,
'Faker',
true,
$format
);
self::assertFileExists($file);

self::checkImageProperties($file, $width, $height, $format);
}
}

private static function checkImageProperties(
string $file,
int $width,
int $height,
string $format
) {
if (function_exists('getimagesize')) {
[$width, $height, $type, $attr] = getimagesize($file);
self::assertEquals(640, $width);
self::assertEquals(480, $height);
self::assertEquals(constant('IMAGETYPE_PNG'), $type);
$imageConstants = Image::getFormatConstants();
[$actualWidth, $actualHeight, $type, $attr] = getimagesize($file);
self::assertEquals($width, $actualWidth);
self::assertEquals($height, $actualHeight);
self::assertEquals($imageConstants[$format], $type);
} else {
self::assertEquals('png', pathinfo($file, PATHINFO_EXTENSION));
self::assertEquals($format, pathinfo($file, PATHINFO_EXTENSION));
}

if (file_exists($file)) {
unlink($file);
}
}

private static function checkUrlConnection(string $url)
{
$curlPing = curl_init($url);
curl_setopt($curlPing, CURLOPT_TIMEOUT, 5);
curl_setopt($curlPing, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curlPing, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlPing, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($curlPing);
$httpCode = curl_getinfo($curlPing, CURLINFO_HTTP_CODE);
curl_close($curlPing);

if ($httpCode < 200 | $httpCode > 300) {
self::markTestSkipped(sprintf('"%s" is offline, skipping test', $url));
}
}
}

0 comments on commit f66a262

Please sign in to comment.