Manual Image Crop - Version 1.08

Version Description

  • More descriptive error messages
  • Russian translation added
  • Hooked 'Crop' link to new media library layout (WP 4.0)
  • A few minor edits
Download this release

Release Info

Developer tomasz.sita
Plugin Icon 128x128 Manual Image Crop
Version 1.08
Comparing to
See all releases

Code changes from version 1.07 to 1.08

assets/css/mic-admin.css CHANGED
@@ -84,7 +84,7 @@
84
 
85
  .mic-editor-wrapper h4 {
86
  float: left;
87
- width: 120px;
88
  margin-top: 23px;
89
  line-height: 11px;
90
  }
84
 
85
  .mic-editor-wrapper h4 {
86
  float: left;
87
+ width: 100px;
88
  margin-top: 23px;
89
  line-height: 11px;
90
  }
assets/js/microp.js CHANGED
@@ -16,11 +16,11 @@ jQuery(document).ready(function($) {
16
  $.post(ajaxurl + '?action=mic_crop_image', { select: jcrop_api.tellSelect(), scaled: jcrop_api.tellScaled(), attachmentId: mic_attachment_id, editedSize: mic_edited_size, previewScale: mic_preview_scale, make2x: $('#mic-make-2x').prop('checked'), mic_quality: $('#micQuality').val() } , function(response) {
17
  if (response.status == 'ok') {
18
  var newImage = new Image();
19
- newImage.src = response.file;
20
  var count = 0;
21
  function updateImage() {
22
  if(newImage.complete) {
23
- $('#micPreviousImage').attr('src', newImage.src);
24
  $('#micCropImage').show();
25
  $('#micSuccessMessage').show().delay(5000).fadeOut();
26
  $('#micLoading').hide();
@@ -30,7 +30,8 @@ jQuery(document).ready(function($) {
30
  }
31
  updateImage();
32
  }else {
33
- $('#micFailureMessage').show().delay(5000).fadeOut();
 
34
  $('#micCropImage').show();
35
  $('#micLoading').hide();
36
  }
16
  $.post(ajaxurl + '?action=mic_crop_image', { select: jcrop_api.tellSelect(), scaled: jcrop_api.tellScaled(), attachmentId: mic_attachment_id, editedSize: mic_edited_size, previewScale: mic_preview_scale, make2x: $('#mic-make-2x').prop('checked'), mic_quality: $('#micQuality').val() } , function(response) {
17
  if (response.status == 'ok') {
18
  var newImage = new Image();
19
+ newImage.src = response.file + '?' + Math.random();
20
  var count = 0;
21
  function updateImage() {
22
  if(newImage.complete) {
23
+ $('img[src^="' + response.file + '"]').attr('src', newImage.src);
24
  $('#micCropImage').show();
25
  $('#micSuccessMessage').show().delay(5000).fadeOut();
26
  $('#micLoading').hide();
30
  }
31
  updateImage();
32
  }else {
33
+ $('#micFailureMessage').show().delay(10000).fadeOut();
34
+ $('#micFailureMessage .error-message').html(response.message);
35
  $('#micCropImage').show();
36
  $('#micLoading').hide();
37
  }
languages/microp-ru_RU.mo ADDED
Binary file
languages/microp-ru_RU.po ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: mic\n"
4
+ "POT-Creation-Date: 2014-05-13 22:40-0000\n"
5
+ "PO-Revision-Date: 2014-09-02 21:55+0700\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.6.9\n"
12
+ "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "Language: ru_RU\n"
15
+ "X-Poedit-SearchPath-0: C:\\wamp\\www\\wordpress\\wp-content\\plugins\\manual-"
16
+ "image-crop\n"
17
+
18
+ #: manual-image-crop/lib/ManualImageCrop.php:58
19
+ msgid "Crop"
20
+ msgstr "Обрезать"
21
+
22
+ #: manual-image-crop/lib/ManualImageCrop.php:67
23
+ msgid "Crop featured image"
24
+ msgstr "Обрезать миниатюру"
25
+
26
+ #: manual-image-crop/lib/ManualImageCrop.php:94
27
+ #: manual-image-crop/lib/ManualImageCrop.php:121
28
+ msgid "Crop Image"
29
+ msgstr "Обрезать изображение"
30
+
31
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:31
32
+ msgid "Pick the image size:"
33
+ msgstr "Выберите размер изображения"
34
+
35
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:41
36
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:115
37
+ msgid "Thumbnail"
38
+ msgstr "Миниатюра"
39
+
40
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:42
41
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:116
42
+ msgid "Medium"
43
+ msgstr "Средний"
44
+
45
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:43
46
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:117
47
+ msgid "Large"
48
+ msgstr "Крупный"
49
+
50
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:44
51
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:118
52
+ msgid "Full Size"
53
+ msgstr "Полный"
54
+
55
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:142
56
+ msgid "Original picture dimensions:"
57
+ msgstr "Оригинальный размер изображения"
58
+
59
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:143
60
+ msgid "Target picture dimensions:"
61
+ msgstr "Целевой размер изображения"
62
+
63
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:143
64
+ msgid "Soft proportional crop mode"
65
+ msgstr "Обрезка с сохранением пропорций"
66
+
67
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:143
68
+ msgid "Hard crop mode"
69
+ msgstr "Жесткая обрезка"
70
+
71
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:147
72
+ msgid "New image:"
73
+ msgstr "Новое изоражение:"
74
+
75
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:154
76
+ msgid "Previous image:"
77
+ msgstr "Предыдущее изображение:"
78
+
79
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:162
80
+ msgid "Crop it!"
81
+ msgstr "Обрезать!"
82
+
83
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:169
84
+ msgid "Target JPEG Quality"
85
+ msgstr "Качество JPEG"
86
+
87
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:170
88
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:154
89
+ msgid "100 (best quality, biggest file)"
90
+ msgstr "100 (лучшее качество, наибольший размер)"
91
+
92
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:171
93
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:155
94
+ msgid "80 (very high quality)"
95
+ msgstr "80 (очень высокое)"
96
+
97
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:172
98
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:156
99
+ msgid "70 (high quality)"
100
+ msgstr "70 (высокое)"
101
+
102
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:173
103
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:157
104
+ msgid "60 (good)"
105
+ msgstr "60 (хорошее)"
106
+
107
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:174
108
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:158
109
+ msgid "50 (average)"
110
+ msgstr "50 (среднее)"
111
+
112
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:175
113
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:159
114
+ msgid "30 (low)"
115
+ msgstr "30 (низкое)"
116
+
117
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:176
118
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:160
119
+ msgid "10 (very low, smallest file)"
120
+ msgstr "10 (очень низкое качество, наименьший размер)"
121
+
122
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:183
123
+ msgid "Generate Retina/HiDPI (@2x):"
124
+ msgstr "Генерировать Retina/HiDPI (@2x):"
125
+
126
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:188
127
+ msgid "The image has been cropped successfully"
128
+ msgstr "Изображение успешно обрезано"
129
+
130
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:189
131
+ msgid "An Error has occured. Please try again or contact plugin's author."
132
+ msgstr "Ошибка. Пожалуйста, попробуйте снова или обратитесь к автору плагина."
133
+
134
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:232
135
+ msgid "Compatible"
136
+ msgstr "Совместимость"
137
+
138
+ #: manual-image-crop/lib/ManualImageCropEditorWindow.php:234
139
+ msgid "Source too small"
140
+ msgstr "Изображение слишком маленькое"
141
+
142
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:125
143
+ msgid "Size"
144
+ msgstr "Размер"
145
+
146
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:126
147
+ msgid "Visible"
148
+ msgstr "Видимость"
149
+
150
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:127
151
+ msgid "Default JPEG Quality"
152
+ msgstr "Качество JPEG по умолчанию"
153
+
154
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:128
155
+ msgid "Custom Label"
156
+ msgstr "Пользовательская метка"
157
+
158
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:150
159
+ msgid "Yes"
160
+ msgstr "Да"
161
+
162
+ #: manual-image-crop/lib/ManualImageCropSettingsPage.php:151
163
+ msgid "No"
164
+ msgstr "Нет"
lib/ManualImageCrop.php CHANGED
@@ -96,6 +96,16 @@ setInterval(function() {
96
  console.log(e);
97
  }
98
  }
 
 
 
 
 
 
 
 
 
 
99
  }, 500);
100
  });
101
  </script>
@@ -211,10 +221,15 @@ setInterval(function() {
211
 
212
  if ( function_exists('wp_get_image_editor') ) {
213
  $img = wp_get_image_editor( $src_file );
 
214
  if ( ! is_wp_error( $img ) ) {
215
- $img->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, false );
 
216
  $img->set_quality( $quality );
217
  $img->save($dst_file);
 
 
 
218
  }
219
  } else {
220
  //determines what's the image format
@@ -226,20 +241,37 @@ setInterval(function() {
226
  } else {
227
  $src_img = imagecreatefromjpeg($src_file);
228
  }
 
 
 
 
 
 
229
  $dst_img = imagecreatetruecolor($dst_w, $dst_h);
230
- imagecopyresampled($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
231
-
 
 
 
 
 
 
232
  if ($ext == "gif"){
233
- imagegif($dst_img, $dst_file);
234
  } else if($ext =="png"){
235
- imagepng($dst_img, $dst_file);
236
  } else {
237
- imagejpeg($dst_img, $dst_file, $quality);
238
  }
 
 
 
 
 
239
  }
240
 
241
  // Generate Retina Image
242
- if($_POST['make2x'] === 'true') {
243
  $dst_w2x = $dst_w * 2;
244
  $dst_h2x = $dst_h * 2;
245
 
@@ -254,25 +286,42 @@ setInterval(function() {
254
  $img->crop( $src_x, $src_y, $src_w, $src_h, $dst_w2x, $dst_h2x, false );
255
  $img->set_quality( $quality );
256
  $img->save($dst_file2x);
257
- }
 
 
 
258
  } else {
259
  $dst_img2x = imagecreatetruecolor($dst_w2x, $dst_h2x);
260
- imagecopyresampled($dst_img2x, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w2x, $dst_h2x, $src_w, $src_h);
 
 
 
 
 
 
 
261
  if ($ext == "gif"){
262
- imagegif($dst_img2x, $dst_file2x);
263
  } else if($ext =="png"){
264
- imagepng($dst_img2x, $dst_file2x);
265
  } else {
266
- imagejpeg($dst_img2x, $dst_file2x, $quality);
 
 
 
 
 
267
  }
268
  }
269
  }
270
  }
271
  // update 'mic_make2x' option status to persist choice
272
- if($_POST['make2x'] !== get_option('mic_make2x')) update_option('mic_make2x', $_POST['make2x']);
 
 
273
 
274
  //returns the url to the generated image (to allow refreshing the preview)
275
- echo json_encode (array('status' => 'ok', 'file' => $dst_file_url[0] . '?' . time() ) );
276
  exit;
277
  }
278
  }
96
  console.log(e);
97
  }
98
  }
99
+
100
+ if (jQuery('.attachment-details .details-image').length) {
101
+ try {
102
+ var postId = jQuery('.attachment-details').attr('data-id');
103
+ jQuery('.button.crop-image-ml.crop-image').remove();
104
+ jQuery('.button.edit-attachment').after( ' <a class="thickbox mic-link crop-image-ml crop-image button" rel="crop" title="Manual Image Crop" href="' + ajaxurl + '?action=mic_editor_window&postId=' + postId + '"><?php _e('Crop Image','microp') ?></a>' );
105
+ } catch (e) {
106
+ console.log(e);
107
+ }
108
+ }
109
  }, 500);
110
  });
111
  </script>
221
 
222
  if ( function_exists('wp_get_image_editor') ) {
223
  $img = wp_get_image_editor( $src_file );
224
+
225
  if ( ! is_wp_error( $img ) ) {
226
+
227
+ $img->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, false );
228
  $img->set_quality( $quality );
229
  $img->save($dst_file);
230
+ }else {
231
+ echo json_encode (array('status' => 'error', 'message' => 'WP_ERROR: ' . $img->get_error_message() ) );
232
+ exit;
233
  }
234
  } else {
235
  //determines what's the image format
241
  } else {
242
  $src_img = imagecreatefromjpeg($src_file);
243
  }
244
+
245
+ if ($src_img === false ) {
246
+ echo json_encode (array('status' => 'error', 'message' => 'PHP ERROR: Cannot create image from the source file' ) );
247
+ exit;
248
+ }
249
+
250
  $dst_img = imagecreatetruecolor($dst_w, $dst_h);
251
+ $resampleReturn = imagecopyresampled($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
252
+
253
+ if ($resampleReturn === false ) {
254
+ echo json_encode (array('status' => 'error', 'message' => 'PHP ERROR: imagecopyresampled' ) );
255
+ exit;
256
+ }
257
+
258
+ $imageSaveReturn = true;
259
  if ($ext == "gif"){
260
+ $imageSaveReturn = imagegif($dst_img, $dst_file);
261
  } else if($ext =="png"){
262
+ $imageSaveReturn = imagepng($dst_img, $dst_file);
263
  } else {
264
+ $imageSaveReturn = imagejpeg($dst_img, $dst_file, $quality);
265
  }
266
+
267
+ if ($imageSaveReturn === false ) {
268
+ echo json_encode (array('status' => 'error', 'message' => 'PHP ERROR: imagejpeg/imagegif/imagepng' ) );
269
+ exit;
270
+ }
271
  }
272
 
273
  // Generate Retina Image
274
+ if( isset( $_POST['make2x'] ) && $_POST['make2x'] === 'true' ) {
275
  $dst_w2x = $dst_w * 2;
276
  $dst_h2x = $dst_h * 2;
277
 
286
  $img->crop( $src_x, $src_y, $src_w, $src_h, $dst_w2x, $dst_h2x, false );
287
  $img->set_quality( $quality );
288
  $img->save($dst_file2x);
289
+ }else {
290
+ echo json_encode (array('status' => 'error', 'message' => 'WP_ERROR: ' . $img->get_error_message() ) );
291
+ exit;
292
+ }
293
  } else {
294
  $dst_img2x = imagecreatetruecolor($dst_w2x, $dst_h2x);
295
+ $resampleReturn = imagecopyresampled($dst_img2x, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w2x, $dst_h2x, $src_w, $src_h);
296
+
297
+ if ($resampleReturn === false ) {
298
+ echo json_encode (array('status' => 'error', 'message' => 'PHP ERROR: imagecopyresampled' ) );
299
+ exit;
300
+ }
301
+
302
+ $imageSaveReturn = true;
303
  if ($ext == "gif"){
304
+ $imageSaveReturn = imagegif($dst_img2x, $dst_file2x);
305
  } else if($ext =="png"){
306
+ $imageSaveReturn = imagepng($dst_img2x, $dst_file2x);
307
  } else {
308
+ $imageSaveReturn = imagejpeg($dst_img2x, $dst_file2x, $quality);
309
+ }
310
+
311
+ if ($imageSaveReturn === false ) {
312
+ echo json_encode (array('status' => 'error', 'message' => 'PHP ERROR: imagejpeg/imagegif/imagepng' ) );
313
+ exit;
314
  }
315
  }
316
  }
317
  }
318
  // update 'mic_make2x' option status to persist choice
319
+ if( isset( $_POST['make2x'] ) && $_POST['make2x'] !== get_option('mic_make2x') ) {
320
+ update_option('mic_make2x', $_POST['make2x']);
321
+ }
322
 
323
  //returns the url to the generated image (to allow refreshing the preview)
324
+ echo json_encode (array('status' => 'ok', 'file' => $dst_file_url[0] ) );
325
  exit;
326
  }
327
  }
lib/ManualImageCropEditorWindow.php CHANGED
@@ -45,7 +45,7 @@ class ManualImageCropEditorWindow {
45
  $sizeLabels = apply_filters( 'image_size_names_choose', array() );
46
 
47
  foreach ($imageSizes as $s) {
48
- if (! $sizesSettings[$s] ) {
49
  $sizesSettings[$s] = array('label' => '', 'quality' => 80, 'visibility' => 'visible');
50
  }
51
 
@@ -185,7 +185,7 @@ class ManualImageCropEditorWindow {
185
  } ?>
186
 
187
  <div id="micSuccessMessage" class="updated below-h2"><?php _e('The image has been cropped successfully','microp') ?></div>
188
- <div id="micFailureMessage" class="error below-h2"><?php _e('An Error has occured. Please try again or contact plugin\'s author.','microp') ?></div>
189
 
190
  </div>
191
  </div>
45
  $sizeLabels = apply_filters( 'image_size_names_choose', array() );
46
 
47
  foreach ($imageSizes as $s) {
48
+ if ( ! isset($sizesSettings[$s]) ) {
49
  $sizesSettings[$s] = array('label' => '', 'quality' => 80, 'visibility' => 'visible');
50
  }
51
 
185
  } ?>
186
 
187
  <div id="micSuccessMessage" class="updated below-h2"><?php _e('The image has been cropped successfully','microp') ?></div>
188
+ <div id="micFailureMessage" class="error below-h2"><span class="error-message"></span><br /><?php _e('An Error has occured. Please try again or contact plugin\'s author.','microp') ?></div>
189
 
190
  </div>
191
  </div>
manual-image-crop.php CHANGED
@@ -3,13 +3,13 @@
3
  Plugin Name: Manual Image Crop
4
  Plugin URI: http://www.rocketmill.co.uk/wordpress-plugin-manual-image-crop
5
  Description: Plugin allows you to manually crop all the image sizes registered in your WordPress theme (in particular featured image). Simply click on the "Crop" link next to any image in your media library and select the area of the image you want to crop.
6
- Version: 1.07
7
  Author: Tomasz Sita
8
  Author URI: http://www.rocketmill.co.uk/author/tomasz
9
  License: GPL2
10
  */
11
 
12
- define('mic_VERSION', '1.07');
13
 
14
 
15
  include_once(dirname(__FILE__) . '/lib/ManualImageCrop.php');
3
  Plugin Name: Manual Image Crop
4
  Plugin URI: http://www.rocketmill.co.uk/wordpress-plugin-manual-image-crop
5
  Description: Plugin allows you to manually crop all the image sizes registered in your WordPress theme (in particular featured image). Simply click on the "Crop" link next to any image in your media library and select the area of the image you want to crop.
6
+ Version: 1.08
7
  Author: Tomasz Sita
8
  Author URI: http://www.rocketmill.co.uk/author/tomasz
9
  License: GPL2
10
  */
11
 
12
+ define('mic_VERSION', '1.08');
13
 
14
 
15
  include_once(dirname(__FILE__) . '/lib/ManualImageCrop.php');
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
  === Manual Image Crop ===
2
  Contributors: tomasz.sita
3
  Tags: crop, cropping, thumbnail, featured image, gallery, images, picture, image, image area
4
- Tested up to: 3.9.2
5
  Requires at least: 3.0.1
6
  License: GPLv2 or later
7
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
8
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WB5ZQWGUM7T96
9
- Stable tag: 1.07
10
 
11
  Plugin allows you to manually crop all the image sizes registered in your WordPress theme (in particular featured image).
12
 
@@ -27,8 +27,9 @@ https://github.com/tomaszsita/wp-manual-image-crop
27
  Translations:
28
  * French (Gabriel Féron)
29
  * German (Bertram Greenhough)
30
- * Italian (htrex)
31
  * Polish (myself)
 
32
  * Spanish (Andrew Kurtis)
33
 
34
  Please contact me if you want to add a translation (or submit a pull request on GitHub)
@@ -45,6 +46,12 @@ Automatically:
45
  * When the plugin has been installed, Click 'Activate'
46
 
47
  == Changelog ==
 
 
 
 
 
 
48
  = 1.07 =
49
  * Fixed 'Cannot use string offset as an array' error
50
 
1
  === Manual Image Crop ===
2
  Contributors: tomasz.sita
3
  Tags: crop, cropping, thumbnail, featured image, gallery, images, picture, image, image area
4
+ Tested up to: 4.0
5
  Requires at least: 3.0.1
6
  License: GPLv2 or later
7
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
8
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WB5ZQWGUM7T96
9
+ Stable tag: 1.08
10
 
11
  Plugin allows you to manually crop all the image sizes registered in your WordPress theme (in particular featured image).
12
 
27
  Translations:
28
  * French (Gabriel Féron)
29
  * German (Bertram Greenhough)
30
+ * Italian (Alessandro Curci)
31
  * Polish (myself)
32
+ * Russian (Andrey Hohlov)
33
  * Spanish (Andrew Kurtis)
34
 
35
  Please contact me if you want to add a translation (or submit a pull request on GitHub)
46
  * When the plugin has been installed, Click 'Activate'
47
 
48
  == Changelog ==
49
+ = 1.08 =
50
+ * More descriptive error messages
51
+ * Russian translation added
52
+ * Hooked 'Crop' link to new media library layout (WP 4.0)
53
+ * A few minor edits
54
+
55
  = 1.07 =
56
  * Fixed 'Cannot use string offset as an array' error
57