| 1 | <?php |
| 2 | require_once dirname( __FILE__ ) . '/base.php'; |
| 3 | |
| 4 | /** |
| 5 | * Test the WP_Image_Editor base class |
| 6 | * |
| 7 | * @group image |
| 8 | * @group media |
| 9 | * @group orientation |
| 10 | */ |
| 11 | class Tests_Image_Editor_Orientation extends WP_Image_UnitTestCase { |
| 12 | |
| 13 | public $editor_engine = 'WP_Image_Editor_Imagick'; |
| 14 | |
| 15 | public function setUp() { |
| 16 | require_once( ABSPATH . WPINC . '/class-wp-image-editor.php' ); |
| 17 | require_once( ABSPATH . WPINC . '/class-wp-image-editor-imagick.php' ); |
| 18 | |
| 19 | parent::setUp(); |
| 20 | } |
| 21 | |
| 22 | /** |
| 23 | * Test removing orientation exif data on rotate |
| 24 | * |
| 25 | * @ticket 37140 |
| 26 | * |
| 27 | * @dataProvider get_images |
| 28 | */ |
| 29 | public function test_remove_orientation_data_on_rotate( $file ) { |
| 30 | |
| 31 | preg_match( '/-(\d)\.(?:jpe?g|png|gif)$/', $file, $matches ); |
| 32 | $orientation_value = intval( $matches[1] ); |
| 33 | |
| 34 | // Make sure we trigger wp_is_edited_image() |
| 35 | $file = $this->get_temp_edited_image( $file ); |
| 36 | |
| 37 | $data = wp_read_image_metadata( $file ); |
| 38 | |
| 39 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation value read from does not match image file exif data: ' . $file ); |
| 40 | |
| 41 | $temp_file = $this->get_temp_edited_image( $file, 'new' ); |
| 42 | |
| 43 | $image = wp_get_image_editor( $file ); |
| 44 | $image->rotate( 180 ); |
| 45 | $image->save( $temp_file ); |
| 46 | |
| 47 | $data = wp_read_image_metadata( $temp_file ); |
| 48 | |
| 49 | $this->assertEquals( 1, intval( $data['orientation'] ), 'Orientation exif data was not updated after rotating image: ' . $file ); |
| 50 | |
| 51 | unlink( $file ); |
| 52 | unlink( $temp_file ); |
| 53 | } |
| 54 | |
| 55 | /** |
| 56 | * Test removing orientation exif data on rotate |
| 57 | * |
| 58 | * @ticket 37140 |
| 59 | * |
| 60 | * @dataProvider get_images |
| 61 | */ |
| 62 | public function test_remove_orientation_data_on_flip( $file ) { |
| 63 | |
| 64 | preg_match( '/-(\d)\.(?:jpe?g|png|gif)$/', $file, $matches ); |
| 65 | $orientation_value = intval( $matches[1] ); |
| 66 | |
| 67 | // Make sure we trigger wp_is_edited_image() |
| 68 | $file = $this->get_temp_edited_image( $file ); |
| 69 | |
| 70 | $data = wp_read_image_metadata( $file ); |
| 71 | |
| 72 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation value read from does not match image file exif data: ' . $file ); |
| 73 | |
| 74 | $temp_file = $this->get_temp_edited_image( $file, 'new' ); |
| 75 | |
| 76 | $image = wp_get_image_editor( $file ); |
| 77 | $image->flip( true, true ); |
| 78 | $image->save( $temp_file ); |
| 79 | |
| 80 | $data = wp_read_image_metadata( $temp_file ); |
| 81 | |
| 82 | $this->assertEquals( 1, intval( $data['orientation'] ), 'Orientation exif data was not updated after flipping image: ' . $file ); |
| 83 | |
| 84 | unlink( $file ); |
| 85 | unlink( $temp_file ); |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Test removing orientation exif data on resize |
| 90 | * |
| 91 | * @ticket 37140 |
| 92 | * |
| 93 | * @dataProvider get_images |
| 94 | */ |
| 95 | public function test_remove_orientation_data_on_resize( $file ) { |
| 96 | |
| 97 | preg_match( '/-(\d)\.(?:jpe?g|png|gif)$/', $file, $matches ); |
| 98 | $orientation_value = intval( $matches[1] ); |
| 99 | |
| 100 | // Make sure we trigger wp_is_edited_image() |
| 101 | $file = $this->get_temp_edited_image( $file ); |
| 102 | |
| 103 | $data = wp_read_image_metadata( $file ); |
| 104 | |
| 105 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation value read from does not match image file exif data: ' . $file ); |
| 106 | |
| 107 | $temp_file = $this->get_temp_edited_image( $file, 'new' ); |
| 108 | |
| 109 | $image = wp_get_image_editor( $file ); |
| 110 | $image->resize( 100, 100, true ); |
| 111 | $image->save( $temp_file ); |
| 112 | |
| 113 | $data = wp_read_image_metadata( $temp_file ); |
| 114 | |
| 115 | $this->assertEquals( 1, intval( $data['orientation'] ), 'Orientation exif data was not updated after resizing image: ' . $file ); |
| 116 | |
| 117 | unlink( $file ); |
| 118 | unlink( $temp_file ); |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * Test removing orientation exif data on crop |
| 123 | * |
| 124 | * @ticket 37140 |
| 125 | * |
| 126 | * @dataProvider get_images |
| 127 | */ |
| 128 | public function test_remove_orientation_data_on_crop( $file ) { |
| 129 | |
| 130 | preg_match( '/-(\d)\.(?:jpe?g|png|gif)$/', $file, $matches ); |
| 131 | $orientation_value = intval( $matches[1] ); |
| 132 | |
| 133 | // Make sure we trigger wp_is_edited_image() |
| 134 | $file = $this->get_temp_edited_image( $file ); |
| 135 | |
| 136 | $data = wp_read_image_metadata( $file ); |
| 137 | |
| 138 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation value read from does not match image file exif data: ' . $file ); |
| 139 | |
| 140 | $temp_file = $this->get_temp_edited_image( $file, 'new' ); |
| 141 | |
| 142 | $image = wp_get_image_editor( $file ); |
| 143 | $image->crop( 0, 0, 100, 100 ); |
| 144 | $image->save( $temp_file ); |
| 145 | |
| 146 | $data = wp_read_image_metadata( $temp_file ); |
| 147 | |
| 148 | $this->assertEquals( 1, intval( $data['orientation'] ), 'Orientation exif data was not updated after cropping image: ' . $file ); |
| 149 | |
| 150 | unlink( $file ); |
| 151 | unlink( $temp_file ); |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Test preserve orientation exif data on resize non edited image |
| 156 | * |
| 157 | * @ticket 37140 |
| 158 | * |
| 159 | * @dataProvider get_images |
| 160 | */ |
| 161 | public function test_preserve_orientation_data_on_resize( $file ) { |
| 162 | |
| 163 | preg_match( '/-(\d)\.(?:jpe?g|png|gif)$/', $file, $matches ); |
| 164 | $orientation_value = intval( $matches[1] ); |
| 165 | |
| 166 | $data = wp_read_image_metadata( $file ); |
| 167 | |
| 168 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation value read from does not match image file exif data: ' . $file ); |
| 169 | |
| 170 | $temp_file = wp_tempnam( $file ) . '.jpg'; |
| 171 | |
| 172 | $image = wp_get_image_editor( $file ); |
| 173 | $image->resize( 100, 100, true ); |
| 174 | $image->save( $temp_file ); |
| 175 | |
| 176 | $data = wp_read_image_metadata( $temp_file ); |
| 177 | |
| 178 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation exif data was not preserved after resizing unedited image: ' . $file ); |
| 179 | |
| 180 | unlink( $temp_file ); |
| 181 | } |
| 182 | |
| 183 | /** |
| 184 | * Test rotating image on upload to normalise image orientation |
| 185 | * |
| 186 | * @ticket 14459 |
| 187 | * |
| 188 | * @dataProvider get_images |
| 189 | */ |
| 190 | public function test_rotate_on_upload( $file ) { |
| 191 | |
| 192 | preg_match( '/-(\d)\.(?:jpe?g|png|gif)$/', $file, $matches ); |
| 193 | $orientation_value = intval( $matches[1] ); |
| 194 | |
| 195 | $image_id = self::factory()->attachment->create_upload_object( $file ); |
| 196 | $image_file = get_attached_file( $image_id ); |
| 197 | $data = wp_read_image_metadata( $image_file ); |
| 198 | |
| 199 | if ( in_array( $orientation_value, array( 3, 5, 8 ), true ) ) { |
| 200 | $this->assertEquals( 1, intval( $data['orientation'] ), 'Orientation exif data was not updated after uploading image: ' . $file ); |
| 201 | } else { |
| 202 | $this->assertEquals( $orientation_value, intval( $data['orientation'] ), 'Orientation exif data was incorrectly modified after uploading image: ' . $file ); |
| 203 | } |
| 204 | |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * dataProvider for images |
| 209 | */ |
| 210 | public function get_images() { |
| 211 | return array_map( function ( $num ) { |
| 212 | return array( DIR_TESTDATA . "/images/orientation-{$num}.jpg" ); |
| 213 | }, range( 1, 8 ) ); |
| 214 | } |
| 215 | |
| 216 | /** |
| 217 | * Make a temporary copy of the image with an edit hash. |
| 218 | * |
| 219 | * @param $file |
| 220 | * @param $modifier |
| 221 | * @return string |
| 222 | */ |
| 223 | protected function get_temp_edited_image( $file, $modifier = '' ) { |
| 224 | $tmp_file = wp_tempnam( basename( $file ) ) . '-e1234567890123.jpg'; |
| 225 | copy( $file, $tmp_file ); |
| 226 | return $tmp_file; |
| 227 | } |
| 228 | |
| 229 | } |