File: /var/www/delta/wp-content/themes/delta/vendor/timber/timber/tests/test-timber-image.php
<?php
use Timber\Image\Operation as ImageOperation;
class TestTimberImage extends TimberImage_UnitTestCase {
/* ----------------
* Helper functions
---------------- */
static function replace_image( $old_id, $new_id ) {
$uploadDir = wp_upload_dir();
$newFile = $uploadDir['basedir'].'/'.get_post_meta($new_id, '_wp_attached_file', true);
$oldFile = $uploadDir['basedir'].'/'.get_post_meta($old_id, '_wp_attached_file', true);
if (!file_exists(dirname($oldFile)))
mkdir(dirname($oldFile), 0777, true);
copy($newFile, $oldFile);
$meta = wp_generate_attachment_metadata($old_id, $oldFile);
wp_update_attachment_metadata($old_id, $meta);
wp_delete_post($new_id, true);
}
static function copyTestImage( $img = 'arch.jpg', $dest_name = null ) {
$upload_dir = wp_upload_dir();
if ( is_null($dest_name) ) {
$dest_name = $img;
}
$destination = $upload_dir['path'].'/'.$dest_name;
copy( __DIR__.'/assets/'.$img, $destination );
return $destination;
}
static function getTestImageURL( $img = 'arch.jpg', $relative = false) {
$upload_dir = wp_upload_dir();
$result = $upload_dir['url'].'/'.$img;
if ( $relative ) {
$result = str_replace(home_url(), '', $result);
}
return $result;
}
public static function is_connected() {
$connected = @fsockopen( "www.google.com", 80, $errno, $errstr, 3 );
if ( $connected ) {
$is_conn = true; //action when connected
fclose( $connected );
} else {
$is_conn = false; //action in connection failure
}
return $is_conn;
}
function add_lang_to_home( $url, $path, $orig_scheme, $blog_id ){
return "$url?lang=en";
}
public static function get_image_attachment( $pid = 0, $file = 'arch.jpg' ) {
$filename = self::copyTestImage( $file );
$filetype = wp_check_filetype( basename( $filename ), null );
$attachment = array('post_title' => 'The Arch', 'post_content' => '', 'post_mime_type' => $filetype['type']);
$iid = wp_insert_attachment( $attachment, $filename, $pid );
return $iid;
}
public function get_post_with_image() {
$pid = self::factory()->post->create();
$iid = self::get_image_attachment( $pid );
add_post_meta( $pid, '_thumbnail_id', $iid, true );
add_post_meta( $iid, '_wp_attachment_metadata', wp_generate_attachment_metadata($iid, get_attached_file($iid)), true );
$post = new TimberPost($pid);
return $post;
}
public static function get_timber_image_object($file = 'cropper.png') {
$iid = self::get_image_attachment(0, $file);
return new TimberImage($iid);
}
/* ----------------
* Tests
---------------- */
function testInitFromID() {
$pid = self::factory()->post->create();
$filename = self::copyTestImage( 'arch.jpg' );
$attachment = array( 'post_title' => 'The Arch', 'post_content' => '' );
$iid = wp_insert_attachment( $attachment, $filename, $pid );
$image = new TimberImage( $iid );
$this->assertEquals( 1500, $image->width() );
}
function testWithOutputBuffer() {
ob_start();
$post = $this->get_post_with_image();
$str = '<img src="{{ post.thumbnail.src|resize(510, 280) }}" />';
Timber::render_string($str, array('post' => $post));
$result = ob_get_contents();
ob_end_clean();
$m = date('m');
$y = date('Y');
$this->assertEquals('<img src="http://example.org/wp-content/uploads/'.$y.'/'.$m.'/arch-510x280-c-default.jpg" />', $result);
}
function testReplacedImage() {
$pid = self::factory()->post->create(array('post_type' => 'post'));
$attach_id = self::get_image_attachment($pid, 'arch.jpg');
$template = '{{Image(img).src|resize(200, 200)}}';
$str = Timber::compile_string($template, array('img' => $attach_id));
$resized_one = Timber\ImageHelper::get_server_location($str);
sleep(1);
$filename = self::copyTestImage('cardinals.jpg', 'arch.jpg');
$str = Timber::compile_string($template, array('img' => $attach_id));
$resized_tester = Timber\ImageHelper::get_server_location($str);
$attach_id = self::get_image_attachment($pid, 'cardinals.jpg');
$str = Timber::compile_string($template, array('img' => $attach_id));
$resized_known = Timber\ImageHelper::get_server_location($str);
$pixel = TestTimberImage::getPixel($resized_one, 5, 5);
$is_white = TestTimberImage::checkPixel($resized_one, 5, 5, '#FFFFFF');
$this->assertTrue($is_white);
$is_also_white = TestTimberImage::checkPixel($resized_one, 5,5, '#FFFFFF');
$this->assertTrue($is_also_white);
}
function testResizedReplacedImage() {
$pid = self::factory()->post->create(array('post_type' => 'post'));
$attach_id = self::get_image_attachment($pid, 'arch.jpg');
$template = '{{Image(img).src|resize(200, 200)}}';
$str = Timber::compile_string($template, array('img' => $attach_id));
$new_id = self::get_image_attachment($pid, 'pizza.jpg');
self::replace_image($attach_id, $new_id);
$str = Timber::compile_string($template, array('img' => $attach_id));
$resized_path = Timber\ImageHelper::get_server_location($str);
$test_md5 = md5( file_get_contents($resized_path) );
$str_pizza = Timber::compile_string($template, array('img' => $new_id));
$resized_pizza = Timber\ImageHelper::get_server_location($str);
$pizza_md5 = md5( file_get_contents($resized_pizza) );
$this->assertEquals($pizza_md5, $test_md5);
}
function testImageLink() {
self::setPermalinkStructure();
$attach = self::get_image_attachment();
$image = new TimberImage($attach);
$links = array();
$links[] = 'http://example.org/'.$image->post_name.'/';
$links[] = 'http://example.org/?attachment_id='.$image->ID;
$this->assertContains($image->link(), $links);
}
function testImageMeta() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
update_post_meta( $image->ID, 'architect', 'Eero Saarinen' );
$this->assertEquals( 'Eero Saarinen', $image->meta( 'architect' ) );
$this->assertEquals( 'Eero Saarinen', $image->architect );
}
function testImageSizes() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$this->assertEquals( 1500, $image->width() );
$this->assertEquals( 1000, $image->height() );
$this->assertEquals( $post->ID, $image->parent()->id );
$this->assertEquals( 1.5, $image->aspect() );
}
function testImageSrcset() {
$post = $this->get_post_with_image();
$img = $post->thumbnail();
$mine = $img->srcset();
$native = wp_get_attachment_image_srcset($img->ID, 'full');
$this->assertEquals($native, $mine);
$native = wp_get_attachment_image_srcset($img->ID, 'medium');
$this->assertNotEquals($native, $mine);
}
function testImageImgSizes() {
$post = $this->get_post_with_image();
$img = $post->thumbnail();
$mine = $img->img_sizes();
$native = wp_get_attachment_image_sizes($img->ID, 'full');
$this->assertEquals($native, $mine);
$native = wp_get_attachment_image_sizes($img->ID, 'medium');
$this->assertNotEquals($native, $mine);
}
/**
* @group maybeSkipped
*/
function testExternalImageResize() {
if ( !self::is_connected() ) {
$this->markTestSkipped('Cannot test external images when not connected to internet');
}
$data = array();
$data['size'] = array( 'width' => 600, 'height' => 400 );
$data['crop'] = 'default';
$filename = 'St._Louis_Gateway_Arch.jpg';
$data['test_image'] = 'http://upload.wikimedia.org/wikipedia/commons/a/aa/'.$filename;
$md5 = md5( $data['test_image'] );
Timber::compile( 'assets/image-test.twig', $data );
$upload_dir = wp_upload_dir();
$path = $upload_dir['path'].'/'.$md5;
/* was the external image D/Ld to the location? */
$this->assertFileExists( $path.'.jpg' );
/* does resize work on external image? */
$resized_path = $path.'-'.$data['size']['width'].'x'.$data['size']['height'].'-c-'.$data['crop'].'.jpg';
$this->assertFileExists( $resized_path );
$old_time = filemtime( $resized_path );
sleep( 1 );
$str = Timber::compile( 'assets/image-test.twig', $data );
$new_time = filemtime( $resized_path );
$this->assertEquals( $old_time, $new_time );
}
function testUpSizing() {
$data = array();
$file_loc = self::copyTestImage( 'stl.jpg' );
$upload_dir = wp_upload_dir();
$new_file = TimberImageHelper::resize( $upload_dir['url'].'/stl.jpg', 500, 200, 'default', true );
$location_of_image = TimberImageHelper::get_server_location( $new_file );
$size = getimagesize( $location_of_image );
$this->assertEquals( 500, $size[0] );
}
function testUpSizing2Param() {
$data = array();
$file_loc = self::copyTestImage( 'stl.jpg' );
$upload_dir = wp_upload_dir();
$new_file = TimberImageHelper::resize( $upload_dir['url'].'/stl.jpg', 500, 300, 'default', true );
$location_of_image = TimberImageHelper::get_server_location( $new_file );
$size = getimagesize( $location_of_image );
$this->assertEquals( 500, $size[0] );
$this->assertEquals( 300, $size[1] );
}
function testImageResizeRelative() {
$upload_dir = wp_upload_dir();
self::copyTestImage();
$url = $upload_dir['url'].'/arch.jpg';
$url = str_replace( 'http://example.org', '', $url );
$data = array( 'crop' => 'default', 'test_image' => $url );
$data['size'] = array( 'width' => 300, 'height' => 300 );
$html = Timber::compile( 'assets/image-test.twig', $data );
$resized_path = $upload_dir['path'].'/arch-'.$data['size']['width'].'x'.$data['size']['height'].'-c-'.$data['crop'].'.jpg';
$this->assertFileExists( $resized_path );
//Now make sure it doesnt regenerage
$old_time = filemtime( $resized_path );
sleep( 1 );
Timber::compile( 'assets/image-test.twig', $data );
$new_time = filemtime( $resized_path );
$this->assertEquals( $old_time, $new_time );
}
function testImageResize() {
$data = array();
$data['size'] = array( 'width' => 600, 'height' => 400 );
$upload_dir = wp_upload_dir();
self::copyTestImage();
$url = $upload_dir['url'].'/arch.jpg';
$data['test_image'] = $url;
$data['crop'] = 'default';
Timber::compile( 'assets/image-test.twig', $data );
$resized_path = $upload_dir['path'].'/arch-'.$data['size']['width'].'x'.$data['size']['height'].'-c-'.$data['crop'].'.jpg';
$this->assertFileExists( $resized_path );
//Now make sure it doesnt regenerage
$old_time = filemtime( $resized_path );
sleep( 1 );
Timber::compile( 'assets/image-test.twig', $data );
$new_time = filemtime( $resized_path );
$this->assertEquals( $old_time, $new_time );
}
function testIsNotAGif() {
$image = self::copyTestImage('arch.jpg');
$this->assertFalse( TimberImageHelper::is_animated_gif($image) );
}
function testIsNotAGifFile() {
$this->assertFalse( TimberImageHelper::is_animated_gif('notreal.gif') );
}
/**
* @group maybeSkipped
*/
function testAnimatedGifResize() {
if ( ! extension_loaded( 'imagick' ) ) {
self::markTestSkipped( 'Animated GIF resizing test requires Imagick extension' );
}
$image = self::copyTestImage('robocop.gif');
$data = array('crop' => 'default');
$data['size'] = array('width' => 90, 'height' => 90);
$upload_dir = wp_upload_dir();
$url = $upload_dir['url'].'/robocop.gif';
$data['test_image'] = $url;
Timber::compile( 'assets/image-test.twig', $data );
$resized_path = $upload_dir['path'].'/robocop-'.$data['size']['width'].'x'.$data['size']['height'].'-c-'.$data['crop'].'.gif';
$this->addFile( $resized_path );
$this->assertFileExists( $resized_path );
$this->assertTrue(TimberImageHelper::is_animated_gif($resized_path));
}
function testImageArray() {
$post_id = self::factory()->post->create();
$filename = self::copyTestImage('arch.jpg');
$wp_filetype = wp_check_filetype( basename( $filename ), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
$data = array('ID' => $attach_id);
$image = new Timber\Image($data);
$filename = explode('/', $image->file);
$filename = array_pop($filename);
$this->assertEquals('arch.jpg', $filename);
}
/**
* @group maybeSkipped
*/
function testResizeTallImage() {
$data = array();
$data['size'] = array( 'width' => 600 );
$upload_dir = wp_upload_dir();
self::copyTestImage( 'tall.jpg' );
$url = $upload_dir['url'].'/tall.jpg';
$data['test_image'] = $url;
$data['crop'] = 'default';
Timber::compile( 'assets/image-test-one-param.twig', $data );
$resized_path = $upload_dir['path'].'/tall-'.$data['size']['width'].'x0'.'-c-'.$data['crop'].'.jpg';
$exists = file_exists( $resized_path );
$this->assertTrue( $exists );
//make sure it's the width it's supposed to be
$image = wp_get_image_editor( $resized_path );
if ( $image instanceof WP_Error ) {
self::markTestSkipped( 'Tall image resizing test is skipped because no image editor is provided by WordPress, make sure that either GD or Imagick extension is installed' );
}
$current_size = $image->get_size();
$w = $current_size['width'];
$this->assertEquals( $w, 600 );
}
function testInitFromRelativePath() {
$filename = self::copyTestImage( 'arch.jpg' );
$path = str_replace(ABSPATH, '/', $filename);
$image = new TimberImage( $path );
$this->assertEquals( 1500, $image->width() );
}
function testImagePath() {
$filename = self::copyTestImage( 'arch.jpg' );
$image = new TimberImage( $filename );
$this->assertStringStartsWith('/wp-content', $image->path());
$this->assertStringEndsWith('.jpg', $image->path());
}
function testInitFromFilePath() {
$image_file = self::copyTestImage();
$image = new TimberImage( $image_file );
$this->assertEquals( 1500, $image->width() );
}
function testInitFromURL() {
$destination_path = self::copyTestImage();
$destination_path = TimberURLHelper::get_rel_path( $destination_path );
$destination_url = 'http://'.$_SERVER['HTTP_HOST'].$destination_path;
$image = new TimberImage( $destination_url );
$this->assertEquals( $destination_url, $image->src() );
$this->assertEquals( $destination_url, (string)$image );
}
function testPostThumbnails() {
$upload_dir = wp_upload_dir();
$post_id = self::factory()->post->create();
$filename = self::copyTestImage( 'flag.png' );
$destination_url = str_replace( ABSPATH, 'http://'.$_SERVER['HTTP_HOST'].'/', $filename );
$wp_filetype = wp_check_filetype( basename( $filename ), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
add_post_meta( $post_id, '_thumbnail_id', $attach_id, true );
$data = array();
$data['post'] = new TimberPost( $post_id );
$data['size'] = array( 'width' => 100, 'height' => 50 );
$data['crop'] = 'default';
Timber::compile( 'assets/thumb-test.twig', $data );
$exists = file_exists( $filename );
$this->assertTrue( $exists );
$resized_path = $upload_dir['path'].'/flag-'.$data['size']['width'].'x'.$data['size']['height'].'-c-'.$data['crop'].'.png';
$exists = file_exists( $resized_path );
$this->assertTrue( $exists );
}
function testImageAltText() {
$upload_dir = wp_upload_dir();
$thumb_alt = 'Thumb alt';
$filename = self::copyTestImage( 'flag.png' );
$wp_filetype = wp_check_filetype( basename( $filename ), null );
$post_id = self::factory()->post->create();
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_excerpt' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
add_post_meta( $post_id, '_thumbnail_id', $attach_id, true );
add_post_meta( $attach_id, '_wp_attachment_image_alt', $thumb_alt, true );
$data = array();
$data['post'] = new TimberPost( $post_id );
$this->assertEquals( $data['post']->thumbnail()->alt(), $thumb_alt );
}
function testResizeFileNaming() {
$file = 'eastern.jpg';
$file_loc = self::copyTestImage( $file );
$upload_dir = wp_upload_dir();
$filename = TimberImageHelper::get_resize_file_url( self::getTestImageURL($file, true), 300, 500, 'default' );
$expected = $upload_dir['relative'].$upload_dir['subdir'].'/eastern-300x500-c-default.jpg';
$this->assertEquals( $expected, $filename );
}
function testResizeFileNamingWithAbsoluteURL() {
$file_loc = self::copyTestImage( 'eastern.jpg' );
$upload_dir = wp_upload_dir();
$url_src = $upload_dir['url'].'/eastern.jpg';
$filename = TimberImageHelper::get_resize_file_url( $url_src, 300, 500, 'default' );
$this->assertEquals( $upload_dir['url'].'/eastern-300x500-c-default.jpg', $filename );
}
function testResizeFileNamingWithLangHome() {
add_filter( 'home_url', array($this, 'add_lang_to_home') , 1, 4 );
$file_loc = self::copyTestImage( 'eastern.jpg' );
$upload_dir = wp_upload_dir();
$url_src = $upload_dir['url'].'/eastern.jpg';
$filename = TimberImageHelper::get_resize_file_url( $url_src, 300, 500, 'default' );
$this->assertEquals( $upload_dir['url'].'/eastern-300x500-c-default.jpg', $filename );
remove_filter( 'home_url', array($this, 'add_lang_to_home'), 1 );
}
function testLetterboxFileNaming() {
$file_loc = self::copyTestImage( 'eastern.jpg' );
$upload_dir = wp_upload_dir();
$url_src = $upload_dir['url'].'/eastern.jpg';
$filename = TimberImageHelper::get_letterbox_file_url( $url_src, 300, 500, '#FFFFFF' );
$this->assertEquals( $upload_dir['url'].'/eastern-lbox-300x500-FFFFFF.jpg', $filename );
}
public static function is_png($file) {
$file = strtolower($file);
if (strpos($file, '.png') > 0) {
return true;
}
return false;
}
public static function is_gif($file) {
$file = strtolower($file);
if (strpos($file, '.gif') > 0) {
return true;
}
return false;
}
public static function checkSize( $file, $width, $height ) {
$size = getimagesize( $file );
if ($width === $size[0] && $height === $size[1]) {
return true;
}
return false;
}
public static function checkChannel($channel, $base, $compare, $upper = false) {
if ($base[$channel] === $base[$channel]) {
return true;
}
if ($upper) {
if ( ($base[$channel] <= $compare[$channel]) && ($compare[$channel] <= $upper[$channel])) {
return true;
}
}
return false;
}
public static function checkPixel($file, $x, $y, $color = false, $upper_color = false) {
if ( self::is_png($file) ) {
$image = imagecreatefrompng( $file );
} else if ( self::is_gif($file) ) {
$image = imagecreatefromgif( $file );
} else {
$image = imagecreatefromjpeg( $file );
}
$pixel_rgba = imagecolorat( $image, $x, $y );
$colors_of_file = imagecolorsforindex( $image, $pixel_rgba );
if ($upper_color) {
$upper_colors = ImageOperation::hexrgb($upper_color);
}
$test_colors = ImageOperation::hexrgb($color);
if( false === $color ) {
$alpha = ($pixel_rgba & 0x7F000000) >> 24;
return $alpha === 127;
}
if ( isset($upper_colors) && $upper_colors ) {
if (self::checkChannel('red', $test_colors, $colors_of_file, $upper_colors) &&
self::checkChannel('green', $test_colors, $colors_of_file, $upper_colors) &&
self::checkChannel('blue', $test_colors, $colors_of_file, $upper_colors)
) {
return true;
}
return false;
}
if ( $test_colors['red'] === $colors_of_file['red'] &&
$test_colors['blue'] === $colors_of_file['blue'] &&
$test_colors['green'] === $colors_of_file['green']) {
return true;
}
return false;
}
function getPixel($file, $x, $y) {
if ( self::is_png($file) ) {
$image = imagecreatefrompng( $file );
} else if ( self::is_gif($file) ) {
$image = imagecreatefromgif( $file );
} else {
$image = imagecreatefromjpeg( $file );
}
$rgb = imagecolorat( $image, $x, $y );
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
return ImageOperation::rgbhex($r, $g, $b);
}
/**
* @group maybeSkipped
*/
function testPNGtoJPG() {
if ( ! extension_loaded( 'gd' ) ) {
self::markTestSkipped( 'PNG to JPEG conversion test requires GD extension' );
}
$file_loc = self::copyTestImage( 'eastern-trans.png' );
$upload_dir = wp_upload_dir();
$new_file = TimberImageHelper::img_to_jpg( $upload_dir['url'].'/eastern-trans.png', '#FFFF00' );
$location_of_image = TimberImageHelper::get_server_location( $new_file );
$this->assertFileExists( $location_of_image );
$image = imagecreatefromjpeg( $location_of_image );
$pixel_rgb = imagecolorat( $image, 1, 1 );
$colors = imagecolorsforindex( $image, $pixel_rgb );
$this->assertEquals( 255, $colors['red'] );
$this->assertEquals( 255, $colors['green'] );
$this->assertEquals( 0, $colors['blue'] );
}
function testImageDeletionSimilarNames() {
$data = array();
$data['size'] = array( 'width' => 500, 'height' => 300 );
$upload_dir = wp_upload_dir();
$file = self::copyTestImage( 'arch-2night.jpg' );
$data['test_image'] = $upload_dir['url'].'/arch-2night.jpg';
$data['crop'] = 'default';
$arch_2night = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
Timber::compile( 'assets/image-test.twig', $data );
$file = self::copyTestImage( 'arch.jpg' );
$data['test_image'] = $upload_dir['url'].'/arch.jpg';
$data['size'] = array( 'width' => 520, 'height' => 250 );
$data['crop'] = 'left';
$arch_regular = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
Timber::compile( 'assets/image-test.twig', $data );
$this->assertFileExists( $arch_regular );
$this->assertFileExists( $arch_2night );
//Delte the regular arch image
TimberImageHelper::delete_generated_files( $file );
//The child of the regular arch image should be like
//poof-be-gone
$this->assertFileDoesNotExist( $arch_regular );
//...but the night image remains!
$this->assertFileExists( $arch_2night );
}
function testImageDeletion() {
$data = array();
$data['size'] = array( 'width' => 500, 'height' => 300 );
$upload_dir = wp_upload_dir();
$file = self::copyTestImage( 'city-museum.jpg' );
$data['test_image'] = $upload_dir['url'].'/city-museum.jpg';
$data['crop'] = 'default';
Timber::compile( 'assets/image-test.twig', $data );
$resized_500_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
$data['size'] = array( 'width' => 520, 'height' => 250 );
$data['crop'] = 'left';
Timber::compile( 'assets/image-test.twig', $data );
$resized_520_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
//make sure it generated the sizes we're expecting
$this->assertFileExists( $resized_500_file );
$this->assertFileExists( $resized_520_file );
//Now delete the "parent" image
TimberImageHelper::delete_generated_files( $file );
//Have the children been deleted as well?
$this->assertFileDoesNotExist( $resized_520_file );
$this->assertFileDoesNotExist( $resized_500_file );
}
function testImageDeletionByURL() {
$post_id = self::factory()->post->create();
$filename = self::copyTestImage( 'flag.png' );
$wp_filetype = wp_check_filetype( basename( $filename ), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
$data = array();
$data['size'] = array( 'width' => 500, 'height' => 300 );
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/flag.png';
$data['crop'] = 'default';
Timber::compile( 'assets/image-test.twig', $data );
$resized_500_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
$data['size'] = array( 'width' => 520, 'height' => 250 );
$data['crop'] = 'left';
Timber::compile( 'assets/image-test.twig', $data );
$resized_520_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
//make sure it generated the sizes we're expecting
$this->assertFileExists( $resized_500_file );
$this->assertFileExists( $resized_520_file );
//Now delete the "parent" image
TimberImageHelper::delete_generated_files( $data['test_image'] );
//Have the children been deleted as well?
$this->assertFileDoesNotExist( $resized_520_file );
$this->assertFileDoesNotExist( $resized_500_file );
}
function testImageDeletionByDeletingAttachment() {
$post_id = self::factory()->post->create();
$filename = self::copyTestImage( 'flag.png' );
$wp_filetype = wp_check_filetype( basename( $filename ), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
$data = array();
$data['size'] = array( 'width' => 500, 'height' => 300 );
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/flag.png';
$data['crop'] = 'default';
Timber::compile( 'assets/image-test.twig', $data );
$resized_500_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
$data['size'] = array( 'width' => 520, 'height' => 250 );
$data['crop'] = 'left';
Timber::compile( 'assets/image-test.twig', $data );
$resized_520_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
//make sure it generated the sizes we're expecting
$this->assertFileExists( $resized_500_file );
$this->assertFileExists( $resized_520_file );
//Now delete the "parent" image
wp_delete_attachment( $attach_id );
//Have the children been deleted as well?
$this->assertFileDoesNotExist( $resized_520_file );
$this->assertFileDoesNotExist( $resized_500_file );
}
function testImageDeletionByAttachmentLocation() {
$post_id = self::factory()->post->create();
$filename = self::copyTestImage( 'flag.png' );
$wp_filetype = wp_check_filetype( basename( $filename ), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
$data = array();
$data['size'] = array( 'width' => 500, 'height' => 300 );
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/flag.png';
$data['crop'] = 'default';
Timber::compile( 'assets/image-test.twig', $data );
$resized_500_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
$data['size'] = array( 'width' => 520, 'height' => 250 );
$data['crop'] = 'left';
Timber::compile( 'assets/image-test.twig', $data );
$resized_520_file = TimberImageHelper::get_resize_file_path( $data['test_image'], $data['size']['width'], $data['size']['height'], $data['crop'] );
//make sure it generated the sizes we're expecting
$this->assertFileExists( $resized_500_file );
$this->assertFileExists( $resized_520_file );
//Now delete the "parent" image
$post = new TimberImage( $attach_id );
TimberImageHelper::delete_generated_files( $post->file_loc );
//Have the children been deleted as well?
$this->assertFileDoesNotExist( $resized_520_file );
$this->assertFileDoesNotExist( $resized_500_file );
}
/**
*
* @group maybeSkipped
*/
function testLetterboxImageDeletion() {
if ( ! extension_loaded( 'gd' ) ) {
self::markTestSkipped( 'Letterbox image test requires GD extension' );
}
$data = array();
$file = self::copyTestImage( 'city-museum.jpg' );
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/city-museum.jpg';
$new_file = TimberImageHelper::letterbox( $data['test_image'], 500, 500, '#00FF00' );
$letterboxed_file = TimberImageHelper::get_letterbox_file_path( $data['test_image'], 500, 500, '#00FF00' );
$this->assertFileExists( $letterboxed_file );
//Now delete the "parent" image
TimberImageHelper::delete_generated_files( $file );
//Have the children been deleted as well?
$this->assertFileDoesNotExist( $letterboxed_file );
}
function _makeThemeImageDirectory() {
$theme_url = get_theme_root_uri().'/'.get_stylesheet();
$img_dir = realpath(get_stylesheet_directory_uri()).'/images';
if ( strpos($img_dir, 'http') === 0 ) {
$img_dir = Timber\URLHelper::url_to_file_system($img_dir);
}
if ( !file_exists($img_dir) ) {
$parent = dirname($img_dir);
chmod($parent, 0777);
$res = mkdir($img_dir, 0777, true);
}
}
function tear_down() {
$theme_url = get_theme_root_uri().'/'.get_stylesheet();
$img_dir = get_stylesheet_directory_uri().'/images';
if ( file_exists($img_dir) ) {
exec(sprintf("rm -rf %s", escapeshellarg($img_dir)));
}
$uploads = wp_upload_dir();
$files = glob($uploads['basedir'].date('/Y/m/').'*');
foreach($files as $file){
if(is_file($file)) {
unlink($file);
}
}
parent::tear_down();
}
function testThemeImageResize() {
$theme_url = get_theme_root_uri().'/'.get_stylesheet();
$source = __DIR__.'/assets/cardinals.jpg';
$dest = get_stylesheet_directory_uri().'/cardinals.jpg';
if ( strpos($dest, 'http') === 0 ) {
$dest = Timber\URLHelper::url_to_file_system($dest);
}
$dest = self::maybe_realpath($dest);
copy($source, $dest);
$this->assertTrue(file_exists($dest));
$image = $theme_url.'/cardinals.jpg';
$image = str_replace( 'http://example.org', '', $image );
$data = array();
$data['test_image'] = $image;
$data['size'] = array( 'width' => 120, 'height' => 120 );
$str = Timber::compile( 'assets/image-test.twig', $data );
$file_location = get_stylesheet_directory_uri().'/cardinals-120x120-c-default.jpg';
if ( strpos($file_location, 'http') === 0 ) {
$file_location = Timber\URLHelper::url_to_file_system($file_location);
}
$file_location = self::maybe_realpath($file_location);
$this->assertFileExists( $file_location );
$this->addFile( $file_location );
}
function maybe_realpath( $path ) {
if ( realpath($path) ) {
return realpath($path);
}
return $path;
}
/**
* @group maybeSkipped
*/
function testThemeImageLetterbox() {
$theme_url = get_theme_root_uri().'/'.get_stylesheet();
if ( ! extension_loaded( 'gd' ) ) {
self::markTestSkipped( 'Letterbox image test requires GD extension' );
}
$source = __DIR__.'/assets/cardinals.jpg';
$dest = self::maybe_realpath(get_template_directory()).'/cardinals.jpg';
copy($source, $dest);
$image = $theme_url.'/cardinals.jpg';
$image = str_replace( 'http://example.org', '', $image );
$letterboxed = TimberImageHelper::letterbox( $image, 600, 300, '#FF0000' );
$this->assertFileExists( realpath(get_template_directory().'/cardinals-lbox-600x300-FF0000.jpg') );
unlink( realpath(get_template_directory().'/cardinals-lbox-600x300-FF0000.jpg') );
}
function testImageWidthWithFilter() {
$pid = self::factory()->post->create();
$photo = $this->copyTestImage();
$photo = TimberURLHelper::get_rel_path($photo);
update_post_meta($pid, 'custom_photo', '/'.$photo);
$str = '{{TimberImage(post.custom_photo).width}}';
$post = new TimberPost($pid);
$rendered = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals( 1500, $rendered );
}
function testResizeNamed() {
add_image_size('timber-testResizeNamed', $width = 600, $height = 400, $crop = true);
$data = array();
$data['size'] = 'timber-testResizeNamed';
$upload_dir = wp_upload_dir();
self::copyTestImage();
$url = $upload_dir['url'].'/arch.jpg';
$data['test_image'] = $url;
Timber::compile('assets/image-resize-named.twig', $data);
$resized_path = $upload_dir['path'].'/arch-'.$width.'x'.$height.'-c-default.jpg';
$this->assertFileExists($resized_path);
//Now make sure it doesn't regenerate
$old_time = filemtime($resized_path);
sleep(1);
Timber::compile('assets/image-resize-named.twig', $data);
$new_time = filemtime($resized_path);
$this->assertEquals($old_time, $new_time);
}
function testBogusResizeNamed() {
$data = array();
$data['size'] = 'timber-foobar';
$upload_dir = wp_upload_dir();
self::copyTestImage();
$url = $upload_dir['url'].'/arch.jpg';
$data['test_image'] = $url;
$result = Timber::compile('assets/image-resize-named.twig', $data);
$this->assertEquals('<img src="'.$url.'" />', trim($result));
}
function testPostThumbnailsNamed() {
add_image_size('timber-testPostThumbnailsNamed', $width = 100, $height = 50, $crop = true);
$upload_dir = wp_upload_dir();
$post_id = self::factory()->post->create();
$filename = self::copyTestImage('flag.png');
$destination_url = str_replace(ABSPATH, 'http://'.$_SERVER['HTTP_HOST'].'/', $filename);
$wp_filetype = wp_check_filetype(basename($filename), null);
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit',
);
$attach_id = wp_insert_attachment($attachment, $filename, $post_id);
add_post_meta($post_id, '_thumbnail_id', $attach_id, true);
$data = array();
$data['post'] = new TimberPost($post_id);
$data['size'] = 'timber-testPostThumbnailsNamed';
Timber::compile('assets/image-thumb-named.twig', $data);
$resized_path = $upload_dir['path'].'/flag-'.$width.'x'.$height.'-c-default.png';
$this->assertFileExists($resized_path);
}
function testPostThumbnailsWithWPName() {
$upload_dir = wp_upload_dir();
$post_id = self::factory()->post->create();
$filename = self::copyTestImage('flag.png');
$destination_url = str_replace(ABSPATH, 'http://'.$_SERVER['HTTP_HOST'].'/', $filename);
$wp_filetype = wp_check_filetype(basename($filename), null);
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit',
);
$attach_id = wp_insert_attachment($attachment, $filename, $post_id);
add_post_meta($post_id, '_thumbnail_id', $attach_id, true);
$data = array();
$data['post'] = new TimberPost($post_id);
$data['size'] = 'medium';
$result = Timber::compile('assets/image-thumb-named.twig', $data);
$filename = 'flag-300x300-c-default.png';
$resized_path = $upload_dir['path'].'/'.$filename;
$this->assertFileExists($resized_path);
$this->assertEquals('<img src="'.$upload_dir['url'].'/'.$filename.'" />', trim($result));
}
function testImageSizeWithWPNameUsingNative(){
require_once('wp-overrides.php');
$filename = __DIR__.'/assets/tom-brady.jpg';
$filesize = filesize($filename);
$data = array('tmp_name' => $filename, 'name' => 'tom-brady.jpg', 'type' => 'image/jpg', 'size' => $filesize, 'error' => 0);
$this->assertTrue(file_exists($filename));
$_FILES['tester'] = $data;
$file_id = WP_Overrides::media_handle_upload('tester', 0, array(), array( 'test_form' => false));
if (!is_int($file_id)) {
error_log(print_r($file_id, true));
}
$image = new TimberImage($file_id);
$str = '<img src="{{image.src(\'medium\')}}" />';
$result = Timber::compile_string($str, array('image' => $image));
$upload_dir = wp_upload_dir();
$this->assertEquals('<img src="'.$upload_dir['url'].'/'.$image->sizes['medium']['file'].'" />', trim($result));
}
function testImageSizeWithWPNameUsingNativeGif(){
require_once('wp-overrides.php');
$filename = __DIR__.'/assets/boyer.gif';
$filesize = filesize($filename);
$data = array('tmp_name' => $filename, 'name' => 'boyer.gif', 'type' => 'image/gif', 'size' => $filesize, 'error' => 0);
$this->assertTrue(file_exists($filename));
$_FILES['tester'] = $data;
$file_id = WP_Overrides::media_handle_upload('tester', 0, array(), array( 'test_form' => false));
if (!is_int($file_id)) {
error_log(print_r($file_id, true));
}
$image = new TimberImage($file_id);
$str = '<img src="{{image.src(\'medium\')}}" />';
$result = Timber::compile_string($str, array('image' => $image));
$upload_dir = wp_upload_dir();
$this->assertEquals('<img src="'.$upload_dir['url'].'/'.$image->sizes['medium']['file'].'" />', trim($result));
}
/**
* @group maybeSkipped
*/
function testGifToJpg() {
if ( ! extension_loaded( 'gd' ) ) {
self::markTestSkipped( 'JPEG conversion test requires GD extension' );
}
$filename = self::copyTestImage('loading.gif');
$gif_url = str_replace(ABSPATH, 'http://'.$_SERVER['HTTP_HOST'].'/', $filename);
$str = '<img src="{{'."'$gif_url'".'|tojpg}}" />';
$result = Timber::compile_string($str);
$jpg_url = str_replace('.gif', '.jpg', $gif_url);
$this->assertEquals('<img src="'.$jpg_url.'" />', $result);
}
function testImageHelperInit() {
$helper = TimberImageHelper::init();
$this->assertTrue($helper);
}
/**
* @group maybeSkipped
*/
function testResizeGif() {
if ( ! extension_loaded( 'imagick' ) ) {
self::markTestSkipped( 'Animated GIF resizing test requires Imagick extension' );
}
$filename = self::copyTestImage('loading.gif');
$gif_url = str_replace(ABSPATH, 'http://'.$_SERVER['HTTP_HOST'].'/', $filename);
$str = '<img src="{{'."'$gif_url'".'|resize(200)}}" />';
$result = Timber::compile_string($str);
$resized_url = str_replace('loading.gif', 'loading-200x0-c-default.gif', $gif_url);
$resized_path = str_replace('http://example.org', ABSPATH, $resized_url);
$resized_path = TimberURLHelper::remove_double_slashes($resized_path);
$this->assertFileExists($resized_path);
}
function testImageNoParent() {
$filename = self::copyTestImage( 'arch.jpg' );
$image = new TimberImage( $filename );
$this->assertFalse($image->parent());
}
function testImageParent() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$this->assertEquals($post->ID, $image->parent()->ID);
}
function testPathInfo() {
$filename = self::copyTestImage( 'arch.jpg' );
$image = new TimberImage( $filename );
$path_parts = $image->get_pathinfo();
$this->assertEquals('jpg', $path_parts['extension']);
}
function testTimberImageFromPost() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$post = get_post($post->ID);
$str = '{{ TimberImage(post).src }}';
$result = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals($image->src(), $result);
}
function testTimberImageFromTimberImage() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$post = new TimberImage($image);
$str = '{{ TimberImage(post).src }}';
$result = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals($image->src(), $result);
}
function testTimberImageFromTimberImageID() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$post = new TimberImage($image->ID);
$str = '{{ TimberImage(post).src }}';
$result = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals($image->src(), $result);
}
function testTimberImageFromImageID() {
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$post = $image->ID;
$str = '{{ TimberImage(post).src }}';
$result = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals($image->src(), $result);
}
function testTimberImageFromAttachment() {
$iid = self::get_image_attachment();
$image = new TimberImage($iid);
$post = get_post($iid);
$str = '{{ TimberImage(post).src }}';
$result = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals($image->src(), $result);
}
// Test document like pdf, docx
function testTimberImageFromDocument() {
$pid = self::factory()->post->create();
$iid = self::get_image_attachment($pid, 'dummy-pdf.pdf');
$attachment = new TimberImage($iid);
$str = '{{ TimberImage(post).src }}';
$result = Timber::compile_string( $str, array('post' => $iid) );
$this->assertEquals('http://example.org/wp-content/uploads/'.date('Y/m').'/dummy-pdf.pdf', $result);
}
function testNoThumbnail() {
$pid = self::factory()->post->create();
$post = new TimberPost($pid);
$str = Timber::compile_string('Image?{{post.thumbnail.src}}', array('post' => $post));
$this->assertEquals('Image?', $str);
}
function testFilteredImageURL() {
add_filter('wp_get_attachment_image_src', function($image, $id, $size, $icon) {
$image = str_replace('jpg', 'jpeg', $image);
return $image;
}, 10, 4);
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$str = '{{ post.thumbnail.src }}';
$result = Timber::compile_string( $str, array('post' => $post) );
$this->assertEquals('http://example.org/wp-content/uploads/'.date('Y/m').'/arch.jpeg', $result);
}
function testTimberImageForExtraSlashes() {
add_filter('upload_dir', array($this, '_filter_upload'), 10, 1);
$post = $this->get_post_with_image();
$image = $post->thumbnail();
$resized_520_file = TimberImageHelper::resize($image->src, 520, 500);
remove_filter('upload_dir', array($this, '_filter_upload'));
$this->assertFalse(strpos($resized_520_file, '//arch-520x500-c-default.jpg') > -1);
}
function _filter_upload($data) {
$data['path'] = $data['basedir'];
$data['url'] = $data['baseurl'];
return $data;
}
function testAnimagedGifResizeWithoutImagick() {
$this->expectException(Twig\Error\RuntimeError::class);
define('TEST_NO_IMAGICK', true);
$image = self::copyTestImage('robocop.gif');
$data = array('crop' => 'default');
$data['size'] = array('width' => 90, 'height' => 90);
$upload_dir = wp_upload_dir();
$url = $upload_dir['url'].'/robocop.gif';
$data['test_image'] = $url;
$str = Timber::compile( 'assets/image-test.twig', $data );
$resized_path = $upload_dir['path'].'/robocop-'.$data['size']['width'].'x'.$data['size']['height'].'-c-'.$data['crop'].'.gif';
$this->addFile( $resized_path );
$this->assertFileExists( $resized_path );
$this->assertFalse(TimberImageHelper::is_animated_gif($resized_path));
}
/**
* Unlike raster (JPEG, PNG, etc.) SVG is vector-type file so resizing
* shouldn't affect the file. Why is this necessary? B/C a user could have
* uploaded an SVG or JPEG to a particular field and we need to handle
* for either case.
*/
function testSVGResize() {
$image = self::copyTestImage('icon-twitter.svg');
$data = [];
$data['size'] = array('width' => 100, 'height' => 50);
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/icon-twitter.svg';
$str = Timber::compile( 'assets/image-test.twig', $data );
$this->assertEquals('<img src="http://example.org/wp-content/uploads/'.date('Y/m').'/icon-twitter.svg" />', trim($str));
}
function testSVGLetterbox() {
$image = self::copyTestImage('icon-twitter.svg');
$data = [];
$data['size'] = array('width' => 100, 'height' => 50);
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/icon-twitter.svg';
$str = Timber::compile_string( '<img src="{{ test_image|letterbox(size.width, size.height) }}" />', $data );
$this->assertEquals('<img src="http://example.org/wp-content/uploads/'.date('Y/m').'/icon-twitter.svg" />', trim($str));
}
function testSVGRetina() {
$image = self::copyTestImage('icon-twitter.svg');
$data = [];
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/icon-twitter.svg';
$str = Timber::compile_string( '<img src="{{ test_image|retina(2) }}" />', $data );
$this->assertEquals('<img src="http://example.org/wp-content/uploads/'.date('Y/m').'/icon-twitter.svg" />', trim($str));
}
function testSVGtoJPG() {
$image = self::copyTestImage('icon-twitter.svg');
$data = [];
$upload_dir = wp_upload_dir();
$data['test_image'] = $upload_dir['url'].'/icon-twitter.svg';
$str = Timber::compile_string( '<img src="{{ test_image|tojpg }}" />', $data );
$this->assertEquals('<img src="http://example.org/wp-content/uploads/'.date('Y/m').'/icon-twitter.svg" />', trim($str));
}
function testSVGDimensions() {
$pid = self::factory()->post->create();
$filename = self::copyTestImage( 'icon-twitter.svg' );
$attachment = array( 'post_title' => 'Twitter Icon', 'post_content' => '' );
$iid = wp_insert_attachment( $attachment, $filename, $pid );
$image = new TimberImage( $iid );
$this->assertEquals( 23, $image->width() );
$this->assertEquals( 20, $image->height() );
}
}