Crop-Thumbnails - Version 0.8.0

Version Description

  • change Constant from CPT_LANG to CROP_THUMBS_LANG
  • change Constant from CPT_VERSION to CROP_THUMBS_VERSION
  • bug fix: wrong calculated scale in the cpt-crop.js (selection will again always fill the maximum space)
  • change behavior: on landscape-ratio-images the selection will be initial in the middle of the image (portrait-ratio-images stay the same - i asume that portrait-ratio images are mostly portraits)
  • add current jcrop (version v0.9.12) directly into the plugin to get rid of the subversion of cpt-crop.js for an prior version of jcrop in wordpress 3.4
  • add settings-option to display debug (js and/or data)
  • handle image-sizes with zero width or height
  • fix notices: not set variables
  • fix warnings: if an image-size is zero
Download this release

Release Info

Developer Volkmar Kantor
Plugin Icon Crop-Thumbnails
Version 0.8.0
Comparing to
See all releases

Code changes from version 0.7.2 to 0.8.0

crop-thumbnails.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin URI: http://wordpress.org/extend/plugins/crop-thumbnails/
5
  * Author: Volkmar Kantor
6
  * Author URI: http://www.totalmedial.de
7
- * Version: 0.7.2
8
  * Description: Crop your thumbnails, the easy way.
9
  *
10
  * License: GPL v3
@@ -25,11 +25,11 @@
25
  */
26
 
27
  //cpt - stands for crop-post-thumbnail
28
- define('CPT_LANG','cpt_lang');
29
- define('CPT_VERSION','0.7.2');
30
 
31
  function cpt_plugin_init() {
32
- load_plugin_textdomain( CPT_LANG, false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' );
33
 
34
  __('Crop your thumbnails, the easy way.');//have to be the same as the plugins-description - for automatic integration into poedit
35
  }
4
  * Plugin URI: http://wordpress.org/extend/plugins/crop-thumbnails/
5
  * Author: Volkmar Kantor
6
  * Author URI: http://www.totalmedial.de
7
+ * Version: 0.8.0
8
  * Description: Crop your thumbnails, the easy way.
9
  *
10
  * License: GPL v3
25
  */
26
 
27
  //cpt - stands for crop-post-thumbnail
28
+ define('CROP_THUMBS_LANG','cpt_lang');
29
+ define('CROP_THUMBS_VERSION','0.8.0');
30
 
31
  function cpt_plugin_init() {
32
+ load_plugin_textdomain( CROP_THUMBS_LANG, false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' );
33
 
34
  __('Crop your thumbnails, the easy way.');//have to be the same as the plugins-description - for automatic integration into poedit
35
  }
css/cpt-window.css CHANGED
@@ -16,7 +16,8 @@
16
  .thumbnail-list li.active { background-color:#aad6f4; border:1px solid #aad6f4; }
17
  .thumbnail-list li span { display:block; font-size:0.8em; }
18
  .thumbnail-list li img { max-width:100%; height: auto; max-height:250px;}
19
- .thumbnail-list li .lowResWarning { font-style: italic; color:#990000;}
 
20
 
21
  .lbl-cpt-same-ratio {font-size:0.9em;}
22
 
@@ -30,4 +31,9 @@ h4 { margin-bottom:0em;}
30
 
31
 
32
  .postTypeDisabledMsg, .waitingWindow { font-size: 2em; font-weight:bold; width: 100%; height:10em; text-align: center; padding: 3em 0; background: transparent url(../images/loading.gif) no-repeat center center; }
33
- .postTypeDisabledMsg { background: none; }
 
 
 
 
 
16
  .thumbnail-list li.active { background-color:#aad6f4; border:1px solid #aad6f4; }
17
  .thumbnail-list li span { display:block; font-size:0.8em; }
18
  .thumbnail-list li img { max-width:100%; height: auto; max-height:250px;}
19
+ .thumbnail-list li .lowResWarning,
20
+ .thumbnail-list li .badParameterWarning { font-style: italic; color:#990000;}
21
 
22
  .lbl-cpt-same-ratio {font-size:0.9em;}
23
 
31
 
32
 
33
  .postTypeDisabledMsg, .waitingWindow { font-size: 2em; font-weight:bold; width: 100%; height:10em; text-align: center; padding: 3em 0; background: transparent url(../images/loading.gif) no-repeat center center; }
34
+ .postTypeDisabledMsg { background: none; }
35
+
36
+ .cpt-debug {clear: left; padding-left:5px;}
37
+ .cpt-debug .cpt-debug-handle { border:1px solid #aaa; background-color:#f1f1f1; padding:0.3em 1em;}
38
+ .cpt-debug.closed .content { display:none; }
39
+ .cpt-debug .content { font-family: monospace;margin-top:0.5em; }
css/options.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ .cpt_settings_paypal { border:1px solid #298CBA; border-radius:3px; background-color:#f6f6f6; max-width:30em; padding:0 0.5em; margin:2em 0; text-align:center; }
2
+ .cpt_settings_submit { margin-top:2em; }
functions/editor.php CHANGED
@@ -1,6 +1,8 @@
1
  <?php
2
  class CropPostThumbnailsEditor {
3
 
 
 
4
  function __construct() {
5
  if ( is_admin() ) {
6
  //add style and javascript
@@ -20,11 +22,11 @@ class CropPostThumbnailsEditor {
20
  $this->cleanWPHead();
21
  $failure_msg = '';
22
  if(!$this->isUserPermitted()) {
23
- $failure_msg = __('An error happend!',CPT_LANG);
24
  } else {
25
  switch(true) {
26
  case isset($_REQUEST['post_id'])://full programm
27
- $this->byPostId();
28
  break;
29
  case isset($_REQUEST['image_id'])://only one image
30
  $this->byImageId();
@@ -36,17 +38,17 @@ class CropPostThumbnailsEditor {
36
  $_REQUEST['parent_post_id'] = intval($_REQUEST['image_by_post_id']);
37
  $this->byImageId();
38
  } else {
39
- $failure_msg = '<div class="listEmptyMsg">'.__('No featured Image set for this post until now.',CPT_LANG).'</div>';
40
  }
41
  break;
42
  default:
43
- $failure_msg = __('An error happend!',CPT_LANG);
44
  break;
45
  }
46
  }
47
 
48
  if(!empty($failure_msg)) {
49
- wp_enqueue_style( 'cpt-window',plugins_url('css/cpt-window.css',dirname(__FILE__)),array('wp-admin'),CPT_VERSION);
50
  $cptContent = $failure_msg;
51
  include_once( dirname(__FILE__).'/../html/template.php' );
52
  }
@@ -57,7 +59,7 @@ class CropPostThumbnailsEditor {
57
  * Display a list of images that are attached to this post_id.
58
  * Hightlight the post-thumbnail (if it is attached to this post_id)
59
  */
60
- function byPostId() {
61
  global $cptSettings;
62
  $options = $cptSettings->getOptions();
63
 
@@ -72,9 +74,9 @@ class CropPostThumbnailsEditor {
72
  $cptContent = '';
73
 
74
  if($this->shouldBeHiddenOnPostType($options,$parent_post_type)) {
75
- $cptContent = '<div class="postTypeDisabledMsg">'.__('Cropping is disabled for this post-type.',CPT_LANG).'</div>';
76
  } elseif($data==false) {
77
- $cptContent = '<div class="listEmptyMsg">'.__('No images in this post yet. You have to upload some via upload dialog.',CPT_LANG).'</div>';
78
  } else {
79
  //the dynamic javascript
80
  ob_start(); ?>
@@ -95,13 +97,13 @@ class CropPostThumbnailsEditor {
95
 
96
  //the content
97
  ob_start();?>
98
- <div class="header"><strong><?php _e('Choose the image you want to crop.',CPT_LANG); ?></strong></div>
99
  <ul class="image-list">
100
  <?php
101
  $counter = 1;
102
  foreach($data as $key=>$image) : ?>
103
  <li class="entry cursor<?php echo (isset($image->is_post_thumbnail) ? ' post-thumbnail' : ''); ?>" rel="<?php echo $image->ID;?>">
104
- <h3><?php echo (isset($image->is_post_thumbnail) ? __('Post Thumbnail',CPT_LANG) : sprintf(__('Image %d',CPT_LANG),$counter));?></h3>
105
  <?php $img_data = wp_get_attachment_image_src($image->ID, 'thumbnail');?>
106
  <img src="<?php echo $img_data[0].'?'.time(); ?>" />
107
  </li>
@@ -114,7 +116,7 @@ class CropPostThumbnailsEditor {
114
  //END the content
115
  }
116
  wp_enqueue_script( 'jquery' );
117
- wp_enqueue_style( 'cpt-window',plugins_url('css/cpt-window.css',dirname(__FILE__)),array('wp-admin'),CPT_VERSION);
118
  include_once( dirname(__FILE__).'/../html/template.php' );
119
  return true;
120
  }
@@ -134,6 +136,7 @@ class CropPostThumbnailsEditor {
134
 
135
 
136
  $options = $cptSettings->getOptions();
 
137
  $image_obj = get_post(intval($_REQUEST['image_id']));
138
 
139
  //$post_id_attached holds the id of the post the image is attached to - can be null/empty
@@ -145,26 +148,37 @@ class CropPostThumbnailsEditor {
145
  //$current_parent_post_type
146
  $current_parent_post_type = '';
147
  $current_parent_post_id = -1;
148
- $_tmp = get_post(intval($_REQUEST['parent_post_id']));
149
- if(!empty($_REQUEST['parent_post_id']) && !empty($_tmp)) {
150
- $current_parent_post_type = $_tmp->post_type;
151
- $current_parent_post_id = $_tmp->ID;
 
 
 
152
  }
153
 
154
  $all_image_sizes = $cptSettings->getImageSizes();
155
- $orig_img = wp_get_attachment_image_src($image_obj->ID, 'full');
 
 
 
 
 
 
156
  $cache_breaker = time();//a additional parameter that will be added to the image-urls to prevent the browser to show a cached image
157
 
 
158
 
159
  //the javascript
160
  ob_start(); ?>
161
  <script>
162
  jQuery(document).ready(function($) {
163
  cpt_lang = new Object();
164
- cpt_lang['bug'] = "<?php _e('bug - this case shouldnt be happend',CPT_LANG);?>";
165
- cpt_lang['warningOriginalToSmall'] = "<?php _e('Warning: the original image is to small to be cropped in good quality with this thumbnail-size.',CPT_LANG);?>";
166
- cpt_lang['selectOne'] = "<?php _e('First, select one image. Then, click once again.',CPT_LANG);?>";
167
  cpt_ajax_nonce = "<?php echo wp_create_nonce($cptSettings->getNonceBase()); ?>";
 
168
  });
169
  </script>
170
  <?php
@@ -184,58 +198,87 @@ jQuery(document).ready(function($) {
184
 
185
  if($this->shouldBeHiddenOnPostType($options,$current_parent_post_type)) : ?>
186
  <div class="cpt-crop-view">
187
- <div class="postTypeDisabledMsg"><?php _e('Cropping is disabled for this post-type.',CPT_LANG); ?></div>
188
  </div>
189
  <?php else : ?>
190
 
191
  <div class="cpt-crop-view">
192
- <?php if($headline) :?><div class="header"><a class="back" href="<?php echo admin_url( 'admin-ajax.php'); ?>?action=croppostthumb_ajax&post_id=<?php echo $current_parent_post_id; ?>"><?php _e('back to image-list',CPT_LANG); ?></a></div><?php endif; ?>
193
- <div class="waitingWindow hidden"><?php _e('Please wait until the Images are cropped.',CPT_LANG); ?></div>
194
  <div class="mainWindow">
195
  <div class="selectionArea cptLeftPane">
196
- <h3><?php _e('Raw',CPT_LANG); ?>: <?php echo $orig_img[1].' '.__('pixel',CPT_LANG)?> x <?php echo $orig_img[2].' '.__('pixel',CPT_LANG) ?></h3>
197
  <img src="<?php echo $orig_img[0]?>" data-values='{"id":<?php echo $image_obj->ID; ?>,"parentId":<?php echo $post_id_attached ?>,"width":<?php echo $orig_img[1]?>,"height":<?php echo $orig_img[2] ?>}' />
198
- <button id="cpt-generate" class="button"><?php _e('save crop',CPT_LANG);?></button>
199
- <h4><?php _e('Quick-Instructions',CPT_LANG);?></h4>
200
  <ul class="step-info">
201
- <li><?php _e('Step 1: Choose an image from the right.',CPT_LANG); ?></li>
202
- <li><?php _e('Step 2: Use the mouse change the size of the rectangle on the image above.',CPT_LANG); ?></li>
203
- <li><?php _e('Step 3: Click on "save crop".',CPT_LANG); ?></li>
204
  </ul>
205
  </div>
206
  <div class="cptRightPane">
207
  <input type="checkbox" name="cpt-same-ratio" value="1" id="cpt-same-ratio" checked="checked" />
208
- <label for="cpt-same-ratio" class="lbl-cpt-same-ratio"><?php _e('select images with same ratio at once',CPT_LANG); ?></label>
209
- <button id="cpt-deselect" class="button"><?php _e('deselect all',CPT_LANG); ?></button>
210
  <ul class="thumbnail-list">
211
- <?php
212
  foreach($all_image_sizes as $img_size_name=>$value) :
213
- if(!$this->shouldSizeBeHidden($options,$img_size_name,$current_parent_post_type)) :
214
- $gcd = $this->gcd($value['width'],$value['height']);
215
- $print_ratio = $value['width']/$gcd.':'.$value['height']/$gcd;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
- $print_cropped = '';
218
- $crop = 0;
219
- $_class= '';
220
  if(!empty($value['crop'])) {
221
- $print_cropped = ' ('.__('cropped',CPT_LANG).')';
 
222
  $crop = 1;
223
  } else {
224
- $_class = 'hidden';
 
 
 
 
 
 
 
 
 
 
 
225
  }
 
 
 
226
  $img_data = wp_get_attachment_image_src($image_obj->ID, $img_size_name);
227
- $ratio = ($value['width']/$gcd) / ($value['height']/$gcd);
228
 
229
  $_lowResWarning = '';
230
  if($this->isLowRes($value,$orig_img)) {
231
- $_lowResWarning = ' <span class="lowResWarning">'.__('Original image to small for good crop-quality!',CPT_LANG).'</span>';
232
  }
233
 
234
  ?>
235
- <li class="<?php echo $_class; ?>" rel="<?php echo $print_ratio; ?>">
236
- <strong><?php echo $img_size_name.$_lowResWarning; ?></strong>
237
- <span class="dimensions"><?php _e('Dimensions:',CPT_LANG) ?> <?php echo $value['width'].' '.__('pixel',CPT_LANG)?> x <?php echo $value['height'].' '.__('pixel',CPT_LANG) ?> <?php echo $print_cropped ?></span>
238
- <span class="ratio"><?php _e('Ratio:',CPT_LANG) ?> <?php echo $print_ratio; ?></span>
239
  <img src="<?php echo $img_data[0]?>?<?php echo $cache_breaker ?>" data-values='{"name":"<?php echo $img_size_name; ?>","width":<?php echo $value['width']; ?>,"height":<?php echo $value['height']; ?>,"ratio":<?php echo $ratio ?>,"crop":<?php echo $crop ?>}' />
240
  </li>
241
  <?php endif; ?>
@@ -247,20 +290,18 @@ jQuery(document).ready(function($) {
247
  <?php
248
  endif;
249
  $cptContent = ob_get_clean();
 
250
  //END the content
251
 
252
 
253
  wp_enqueue_script( 'jquery' );
254
- wp_enqueue_script( 'jcrop' );
255
  wp_enqueue_script( 'json2' );
256
- if(cptGetWpVersion() < 3.5) {
257
- wp_enqueue_script( 'cpt-crop', plugins_url('js/vers-0-7-0/cpt-crop.js',dirname(__FILE__)));
258
- } else {
259
- wp_enqueue_script( 'cpt-crop', plugins_url('js/cpt-crop.js',dirname(__FILE__)));
260
- }
261
 
262
- wp_enqueue_style( 'cpt-window',plugins_url('css/cpt-window.css',dirname(__FILE__)),array('wp-admin'),CPT_VERSION);
263
- wp_enqueue_style( 'jcrop' );
264
  include_once( dirname(__FILE__).'/../html/template.php' );
265
 
266
  $content_width = $_remember_content_width;//reset the content-width
@@ -284,16 +325,29 @@ jQuery(document).ready(function($) {
284
  * @param string name post-type (i.e. post, page, ...)
285
  * @return boolean true if Image-size should be hidden
286
  */
287
- function shouldSizeBeHidden($options,$img_size_name,$post_type='') {
288
- if(empty($post_type)) {
289
- return false;
290
- }
291
-
292
- if(empty($options['hide_size'][$post_type][$img_size_name])) {
293
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  }
295
-
296
- return true;
297
  }
298
 
299
 
@@ -400,6 +454,18 @@ jQuery(document).ready(function($) {
400
  }
401
 
402
 
 
 
 
 
 
 
 
 
 
 
 
 
403
 
404
  /**
405
  * adds the links into post-types and the media-library
@@ -417,11 +483,11 @@ jQuery(document).ready(function($) {
417
  post_id_hidden = parseInt(post_id_hidden.val());
418
 
419
  /** add link on top of editor **/
420
- $('#wp-content-media-buttons').append('<a style="margin:0 2em;" class="thickbox" href="' + ajaxurl + '?action=croppostthumb_ajax&amp;post_id=' + post_id_hidden + '&amp;TB_iframe=1&amp;width=800&amp;height=' + boxViewportHeight + '" title="<?php esc_attr_e('Crop Thumbnails',CPT_LANG) ?>"><?php esc_html_e('Crop Thumbnails',CPT_LANG); ?></a>');
421
 
422
 
423
  /** add link to featured image box **/
424
- var featuredImageLink = $('<a class="thickbox" href="' + ajaxurl + '?action=croppostthumb_ajax&amp;image_by_post_id=' + post_id_hidden + '&amp;viewmode=single&amp;TB_iframe=1&amp;width=800&amp;height=' + boxViewportHeight + '" title="<?php esc_attr_e('Crop Featured Image',CPT_LANG) ?>"><?php esc_html_e('Crop Featured Image',CPT_LANG); ?></a>')
425
  .css({'margin':'5px', 'padding':'5px','display':'inline-block','line-height':'1'})
426
  .addClass('button');
427
  $('#postimagediv .inside').after(featuredImageLink);
@@ -435,7 +501,7 @@ jQuery(document).ready(function($) {
435
  var post_id = parseInt($(this).attr('id').substr(5));
436
  var last_span = $(this).find('.column-title .row-actions span:last-child');
437
  last_span.append(' | ');
438
- last_span.parent().append('<a class="thickbox" href="' + ajaxurl + '?action=croppostthumb_ajax&amp;image_id=' + post_id + '&amp;viewmode=single&amp;TB_iframe=1&amp;width=800&amp;height=' + boxViewportHeight + '" title="<?php esc_attr_e('Crop Thumbnail',CPT_LANG) ?>"><?php esc_html_e('Crop Thumbnail',CPT_LANG); ?></a>')
439
  }
440
  });
441
  }
1
  <?php
2
  class CropPostThumbnailsEditor {
3
 
4
+ private $debugOutput = '';
5
+
6
  function __construct() {
7
  if ( is_admin() ) {
8
  //add style and javascript
22
  $this->cleanWPHead();
23
  $failure_msg = '';
24
  if(!$this->isUserPermitted()) {
25
+ $failure_msg = __('An error happend!',CROP_THUMBS_LANG);
26
  } else {
27
  switch(true) {
28
  case isset($_REQUEST['post_id'])://full programm
29
+ $this->listImages();
30
  break;
31
  case isset($_REQUEST['image_id'])://only one image
32
  $this->byImageId();
38
  $_REQUEST['parent_post_id'] = intval($_REQUEST['image_by_post_id']);
39
  $this->byImageId();
40
  } else {
41
+ $failure_msg = '<div class="listEmptyMsg">'.__('No featured Image set for this post until now.',CROP_THUMBS_LANG).'</div>';
42
  }
43
  break;
44
  default:
45
+ $failure_msg = __('An error happend!',CROP_THUMBS_LANG);
46
  break;
47
  }
48
  }
49
 
50
  if(!empty($failure_msg)) {
51
+ wp_enqueue_style( 'cpt-window',plugins_url('css/cpt-window.css',dirname(__FILE__)),array('wp-admin'),CROP_THUMBS_VERSION);
52
  $cptContent = $failure_msg;
53
  include_once( dirname(__FILE__).'/../html/template.php' );
54
  }
59
  * Display a list of images that are attached to this post_id.
60
  * Hightlight the post-thumbnail (if it is attached to this post_id)
61
  */
62
+ function listImages() {
63
  global $cptSettings;
64
  $options = $cptSettings->getOptions();
65
 
74
  $cptContent = '';
75
 
76
  if($this->shouldBeHiddenOnPostType($options,$parent_post_type)) {
77
+ $cptContent = '<div class="postTypeDisabledMsg">'.__('Cropping is disabled for this post-type.',CROP_THUMBS_LANG).'</div>';
78
  } elseif($data==false) {
79
+ $cptContent = '<div class="listEmptyMsg">'.__('No images in this post yet. You have to upload some via upload dialog.',CROP_THUMBS_LANG).'</div>';
80
  } else {
81
  //the dynamic javascript
82
  ob_start(); ?>
97
 
98
  //the content
99
  ob_start();?>
100
+ <div class="header"><strong><?php _e('Choose the image you want to crop.',CROP_THUMBS_LANG); ?></strong></div>
101
  <ul class="image-list">
102
  <?php
103
  $counter = 1;
104
  foreach($data as $key=>$image) : ?>
105
  <li class="entry cursor<?php echo (isset($image->is_post_thumbnail) ? ' post-thumbnail' : ''); ?>" rel="<?php echo $image->ID;?>">
106
+ <h3><?php echo (isset($image->is_post_thumbnail) ? __('Post Thumbnail',CROP_THUMBS_LANG) : sprintf(__('Image %d',CROP_THUMBS_LANG),$counter));?></h3>
107
  <?php $img_data = wp_get_attachment_image_src($image->ID, 'thumbnail');?>
108
  <img src="<?php echo $img_data[0].'?'.time(); ?>" />
109
  </li>
116
  //END the content
117
  }
118
  wp_enqueue_script( 'jquery' );
119
+ wp_enqueue_style( 'cpt-window',plugins_url('css/cpt-window.css',dirname(__FILE__)),array('wp-admin'),CROP_THUMBS_VERSION);
120
  include_once( dirname(__FILE__).'/../html/template.php' );
121
  return true;
122
  }
136
 
137
 
138
  $options = $cptSettings->getOptions();
139
+ $this->addDebug('options', print_r($options,true));
140
  $image_obj = get_post(intval($_REQUEST['image_id']));
141
 
142
  //$post_id_attached holds the id of the post the image is attached to - can be null/empty
148
  //$current_parent_post_type
149
  $current_parent_post_type = '';
150
  $current_parent_post_id = -1;
151
+
152
+ if(!empty($_REQUEST['parent_post_id'])) {
153
+ $_tmp = get_post(intval($_REQUEST['parent_post_id']));
154
+ if(!empty($_tmp)) {
155
+ $current_parent_post_type = $_tmp->post_type;
156
+ $current_parent_post_id = $_tmp->ID;
157
+ }
158
  }
159
 
160
  $all_image_sizes = $cptSettings->getImageSizes();
161
+ $this->addDebug('all_image_sizes', print_r($all_image_sizes,true));
162
+
163
+ $orig_img = wp_get_attachment_image_src($image_obj->ID, 'full');
164
+ $orig_img['gcd'] = $this->gcd($orig_img[1],$orig_img[2]);
165
+ $orig_img['ratio'] = ($orig_img[1]/$orig_img['gcd']) / ($orig_img[2]/$orig_img['gcd']);
166
+ $orig_img['print_ratio'] = ($orig_img[1]/$orig_img['gcd']).':'.($orig_img[2]/$orig_img['gcd']);
167
+
168
  $cache_breaker = time();//a additional parameter that will be added to the image-urls to prevent the browser to show a cached image
169
 
170
+ $this->addDebug('img-postmeta',print_r(wp_get_attachment_metadata($image_obj->ID, true),true));
171
 
172
  //the javascript
173
  ob_start(); ?>
174
  <script>
175
  jQuery(document).ready(function($) {
176
  cpt_lang = new Object();
177
+ cpt_lang['bug'] = "<?php _e('bug - this case shouldnt be happend',CROP_THUMBS_LANG);?>";
178
+ cpt_lang['warningOriginalToSmall'] = "<?php _e('Warning: the original image is to small to be cropped in good quality with this thumbnail-size.',CROP_THUMBS_LANG);?>";
179
+ cpt_lang['selectOne'] = "<?php _e('First, select one image. Then, click once again.',CROP_THUMBS_LANG);?>";
180
  cpt_ajax_nonce = "<?php echo wp_create_nonce($cptSettings->getNonceBase()); ?>";
181
+ cpt_debug_js = <?php echo (!empty($options['debug_js'])) ? 'true;' : 'false;'; ?>
182
  });
183
  </script>
184
  <?php
198
 
199
  if($this->shouldBeHiddenOnPostType($options,$current_parent_post_type)) : ?>
200
  <div class="cpt-crop-view">
201
+ <div class="postTypeDisabledMsg"><?php _e('Cropping is disabled for this post-type.',CROP_THUMBS_LANG); ?></div>
202
  </div>
203
  <?php else : ?>
204
 
205
  <div class="cpt-crop-view">
206
+ <?php if($headline) :?><div class="header"><a class="back" href="<?php echo admin_url( 'admin-ajax.php'); ?>?action=croppostthumb_ajax&post_id=<?php echo $current_parent_post_id; ?>"><?php _e('back to image-list',CROP_THUMBS_LANG); ?></a></div><?php endif; ?>
207
+ <div class="waitingWindow hidden"><?php _e('Please wait until the Images are cropped.',CROP_THUMBS_LANG); ?></div>
208
  <div class="mainWindow">
209
  <div class="selectionArea cptLeftPane">
210
+ <h3><?php _e('Raw',CROP_THUMBS_LANG); ?>: <?php echo $orig_img[1].' '.__('pixel',CROP_THUMBS_LANG)?> x <?php echo $orig_img[2].' '.__('pixel',CROP_THUMBS_LANG) ?> (<?php echo $orig_img['print_ratio']; ?>)</h3>
211
  <img src="<?php echo $orig_img[0]?>" data-values='{"id":<?php echo $image_obj->ID; ?>,"parentId":<?php echo $post_id_attached ?>,"width":<?php echo $orig_img[1]?>,"height":<?php echo $orig_img[2] ?>}' />
212
+ <button id="cpt-generate" class="button"><?php _e('save crop',CROP_THUMBS_LANG);?></button>
213
+ <h4><?php _e('Quick-Instructions',CROP_THUMBS_LANG);?></h4>
214
  <ul class="step-info">
215
+ <li><?php _e('Step 1: Choose an image from the right.',CROP_THUMBS_LANG); ?></li>
216
+ <li><?php _e('Step 2: Use the mouse change the size of the rectangle on the image above.',CROP_THUMBS_LANG); ?></li>
217
+ <li><?php _e('Step 3: Click on "save crop".',CROP_THUMBS_LANG); ?></li>
218
  </ul>
219
  </div>
220
  <div class="cptRightPane">
221
  <input type="checkbox" name="cpt-same-ratio" value="1" id="cpt-same-ratio" checked="checked" />
222
+ <label for="cpt-same-ratio" class="lbl-cpt-same-ratio"><?php _e('select images with same ratio at once',CROP_THUMBS_LANG); ?></label>
223
+ <button id="cpt-deselect" class="button"><?php _e('deselect all',CROP_THUMBS_LANG); ?></button>
224
  <ul class="thumbnail-list">
225
+ <?php
226
  foreach($all_image_sizes as $img_size_name=>$value) :
227
+ if(!$this->shouldSizeBeHidden($options,$img_size_name,$value,$current_parent_post_type)) :
228
+ $ratio = null; //reset
229
+ $gcd = null; //reset
230
+ $print_ratio = null; //reset
231
+ $print_cropped = ''; //reset
232
+ $crop = 0; //reset
233
+ $special_warning = ''; //reset
234
+
235
+ /** define ratio **/
236
+ if($value['width'] != 0 && $value['height']!=0) {
237
+ $gcd = $this->gcd($value['width'],$value['height']);//get greatest common divisor
238
+ $ratio = ($value['width']/$gcd) / ($value['height']/$gcd);//get ratio
239
+ $print_ratio = $value['width']/$gcd.':'.$value['height']/$gcd;
240
+ } else {
241
+ //keep ratio same as original image
242
+ $gcd = $orig_img['gcd'];
243
+ $ratio = $orig_img['ratio'];
244
+ $print_ratio = $orig_img['print_ratio'];
245
+ }
246
+
247
 
 
 
 
248
  if(!empty($value['crop'])) {
249
+ //cropped
250
+ $print_cropped = ' ('.__('cropped',CROP_THUMBS_LANG).')';
251
  $crop = 1;
252
  } else {
253
+ //not cropped
254
+ /* -- maybe use this behaviour in a later version --
255
+ $print_cropped = ' ('.__('maximum',CROP_THUMBS_LANG).')';
256
+ $print_ratio = __('free choice',CROP_THUMBS_LANG);
257
+ */
258
+
259
+ $print_cropped = ' ('.__('maximum',CROP_THUMBS_LANG).')';
260
+ $crop = 1;
261
+ //keep ratio same as original image
262
+ $gcd = $orig_img['gcd'];
263
+ $ratio = $orig_img['ratio'];
264
+ $print_ratio = $orig_img['print_ratio'];
265
  }
266
+
267
+ $print_dimensions = $value['width'].' '.__('pixel',CROP_THUMBS_LANG).' x '.$value['height'].' '.__('pixel',CROP_THUMBS_LANG).$print_cropped;
268
+
269
  $img_data = wp_get_attachment_image_src($image_obj->ID, $img_size_name);
270
+
271
 
272
  $_lowResWarning = '';
273
  if($this->isLowRes($value,$orig_img)) {
274
+ $_lowResWarning = ' <span class="lowResWarning">'.__('Original image to small for good crop-quality!',CROP_THUMBS_LANG).'</span>';
275
  }
276
 
277
  ?>
278
+ <li rel="<?php echo $print_ratio; ?>">
279
+ <strong><?php echo $img_size_name.$_lowResWarning; ?></strong><?php echo $special_warning; ?>
280
+ <span class="dimensions"><?php _e('Dimensions:',CROP_THUMBS_LANG) ?> <?php echo $print_dimensions; ?></span>
281
+ <span class="ratio"><?php _e('Ratio:',CROP_THUMBS_LANG) ?> <?php echo $print_ratio; ?></span>
282
  <img src="<?php echo $img_data[0]?>?<?php echo $cache_breaker ?>" data-values='{"name":"<?php echo $img_size_name; ?>","width":<?php echo $value['width']; ?>,"height":<?php echo $value['height']; ?>,"ratio":<?php echo $ratio ?>,"crop":<?php echo $crop ?>}' />
283
  </li>
284
  <?php endif; ?>
290
  <?php
291
  endif;
292
  $cptContent = ob_get_clean();
293
+ $cptContent.= $this->getDebugOutput($options);
294
  //END the content
295
 
296
 
297
  wp_enqueue_script( 'jquery' );
298
+ wp_enqueue_script( 'my_jcrop', plugins_url('js/jcrop/js/jquery.Jcrop.min.js',dirname(__FILE__)), array(), CROP_THUMBS_VERSION);
299
  wp_enqueue_script( 'json2' );
300
+ wp_enqueue_script( 'cpt-crop', plugins_url('js/cpt-crop.js',dirname(__FILE__)), array('jquery','my_jcrop','json2'), CROP_THUMBS_VERSION);
301
+
302
+ wp_enqueue_style( 'cpt-window', plugins_url('css/cpt-window.css',dirname(__FILE__)), array('wp-admin'), CROP_THUMBS_VERSION);
303
+ wp_enqueue_style( 'my_jcrop', plugins_url('js/jcrop/css/jquery.Jcrop.min.css',dirname(__FILE__)), array(), CROP_THUMBS_VERSION);
 
304
 
 
 
305
  include_once( dirname(__FILE__).'/../html/template.php' );
306
 
307
  $content_width = $_remember_content_width;//reset the content-width
325
  * @param string name post-type (i.e. post, page, ...)
326
  * @return boolean true if Image-size should be hidden
327
  */
328
+ function shouldSizeBeHidden($options, $img_size_name, $img_size, $post_type='') {
329
+ $_return = false;
330
+ if(!empty($post_type)) {
331
+ //we are NOT in the mediathek
332
+
333
+ //-if hide_size
334
+ if(!empty($options['hide_size'][$post_type][$img_size_name])) {
335
+ $_return = true;
336
+ }
337
+
338
+ //if not a crop-size and allow_non_cropped
339
+ if(empty($img_size['crop']) && empty($options['allow_non_cropped'])) {
340
+ $_return = true;
341
+ }
342
+ } else {
343
+ //we are in the mediathek
344
+
345
+ //-if not a crop-size and allow_non_cropped
346
+ if(empty($img_size['crop']) && empty($options['allow_non_cropped'])) {
347
+ $_return = true;
348
+ }
349
  }
350
+ return $_return;
 
351
  }
352
 
353
 
454
  }
455
 
456
 
457
+ function addDebug($title, $output) {
458
+ $this->debugOutput.= '---'.$title.'---<br />'.$output.'<br />';
459
+ }
460
+
461
+
462
+ function getDebugOutput($options) {
463
+ if(!empty($options['debug_data'])) {
464
+ return '<div class="cpt-debug closed"><a class="cpt-debug-handle" href="#">show debug</a><div class="content">'.nl2br(str_replace(" ","&nbsp;&nbsp;",$this->debugOutput)).'</div></div>';
465
+ }
466
+ return '';
467
+ }
468
+
469
 
470
  /**
471
  * adds the links into post-types and the media-library
483
  post_id_hidden = parseInt(post_id_hidden.val());
484
 
485
  /** add link on top of editor **/
486
+ $('#wp-content-media-buttons').append('<a style="margin:0 2em;" class="thickbox" href="' + ajaxurl + '?action=croppostthumb_ajax&amp;post_id=' + post_id_hidden + '&amp;TB_iframe=1&amp;width=800&amp;height=' + boxViewportHeight + '" title="<?php esc_attr_e('Crop Thumbnails',CROP_THUMBS_LANG) ?>"><?php esc_html_e('Crop Thumbnails',CROP_THUMBS_LANG); ?></a>');
487
 
488
 
489
  /** add link to featured image box **/
490
+ var featuredImageLink = $('<a class="thickbox" href="' + ajaxurl + '?action=croppostthumb_ajax&amp;image_by_post_id=' + post_id_hidden + '&amp;viewmode=single&amp;TB_iframe=1&amp;width=800&amp;height=' + boxViewportHeight + '" title="<?php esc_attr_e('Crop Featured Image',CROP_THUMBS_LANG) ?>"><?php esc_html_e('Crop Featured Image',CROP_THUMBS_LANG); ?></a>')
491
  .css({'margin':'5px', 'padding':'5px','display':'inline-block','line-height':'1'})
492
  .addClass('button');
493
  $('#postimagediv .inside').after(featuredImageLink);
501
  var post_id = parseInt($(this).attr('id').substr(5));
502
  var last_span = $(this).find('.column-title .row-actions span:last-child');
503
  last_span.append(' | ');
504
+ last_span.parent().append('<a class="thickbox" href="' + ajaxurl + '?action=croppostthumb_ajax&amp;image_id=' + post_id + '&amp;viewmode=single&amp;TB_iframe=1&amp;width=800&amp;height=' + boxViewportHeight + '" title="<?php esc_attr_e('Crop Thumbnail',CROP_THUMBS_LANG) ?>"><?php esc_html_e('Crop Thumbnail',CROP_THUMBS_LANG); ?></a>')
505
  }
506
  });
507
  }
functions/save.php CHANGED
@@ -4,6 +4,8 @@ add_action( 'wp_ajax_cptSaveThumbnail', array($cptSave, 'saveThumbnail') );
4
 
5
  class CptSaveThumbnail {
6
 
 
 
7
  /**
8
  * Handle-function called via ajax request.
9
  * Check and crop multiple Images. Update with wp_update_attachment_metadata if needed.
@@ -16,22 +18,20 @@ class CptSaveThumbnail {
16
  */
17
  function saveThumbnail() {
18
  global $cptSettings;
19
- $debug = "saveThumbnail()\n-------------------";
20
  $json_return = array();
21
 
22
  try {
23
  /** get data **/
24
  $upload_dir = wp_upload_dir();
25
  $tmp_dir = $upload_dir['basedir']."/tmp/";
26
-
27
  //from $_REQUEST
28
  $selection = json_decode(stripcslashes($_REQUEST['selection']));
29
  $sourceImgData = json_decode(stripcslashes($_REQUEST['raw_values']));
30
  $targetImgData = json_decode(stripcslashes($_REQUEST['active_values']));
31
 
32
  //from DB
33
-
34
- $imageSizes = $cptSettings->getImageSizes();
35
 
36
  $obj = get_post($sourceImgData->id);
37
  $sourceImgPath = get_attached_file( $obj->ID );
@@ -53,8 +53,11 @@ class CptSaveThumbnail {
53
  $_changed_image_format = false;
54
  $_processing_error = array();
55
  foreach($targetImgData as $_imageSize) {
 
 
56
  $_delete_old_file = '';
57
- if(!$this->isImageSizeValid($_imageSize,$imageSizes)) {
 
58
  continue;
59
  }
60
  if(empty($post_metadata['sizes'][$_imageSize->name])) {
@@ -74,8 +77,16 @@ class CptSaveThumbnail {
74
  $_filepath = $this->generateFilename($sourceImgPath, $_imageSize->width, $_imageSize->height);
75
  $_filepath_info = pathinfo($_filepath);
76
  $_tmp_filepath = $tmp_dir.$_filepath_info['basename'];
77
- $debug.= "thumb:".$_filepath."\n";
78
- $debug.= "thumb tmp:".$_tmp_filepath."\n";
 
 
 
 
 
 
 
 
79
 
80
  $result = wp_crop_image( // * @return string|WP_Error|false New filepath on success, WP_Error or false on failure.
81
  intval($sourceImgData->id), // * @param string|int $src The source file or Attachment ID.
@@ -83,27 +94,26 @@ class CptSaveThumbnail {
83
  $selection->y, // * @param int $src_y The start y position to crop from.
84
  $selection->x2 - $selection->x, // * @param int $src_w The width to crop.
85
  $selection->y2 - $selection->y, // * @param int $src_h The height to crop.
86
- $_imageSize->width, // * @param int $dst_w The destination width.
87
- $_imageSize->height, // * @param int $dst_h The destination height.
88
- false, // ??? // * @param int $src_abs Optional. If the source crop points are absolute.
89
  $_tmp_filepath // * @param string $dst_file Optional. The destination file to write to.
90
  );
91
- #$debug.= "\nresult:".$result."\n";
92
 
93
  $_error = false;
94
  if(empty($result)) {
95
- $_processing_error[] = sprintf(__('Cant generate filesize "%s".',CPT_LANG),$_imageSize->name);
96
  $_error = true;
97
  } else {
98
  if(!empty($_delete_old_file)) {
99
  @unlink($_filepath_info['dirname'].'/'.$_delete_old_file);
100
  }
101
  if(!@copy($result,$_filepath)) {
102
- $_processing_error[] = sprintf(__('Cant copy temporary file to media-library.',CPT_LANG));
103
  $_error = true;
104
  }
105
  if(!@unlink($result)) {
106
- $_processing_error[] = sprintf(__('Cant delete temporary file.',CPT_LANG));
107
  $_error = true;
108
  }
109
  }
@@ -112,12 +122,14 @@ class CptSaveThumbnail {
112
  //update metadata --> otherwise new sizes will not be updated
113
  $_new_meta = array(
114
  'file'=>$_filepath_info['basename'],
115
- 'width'=>intval($_imageSize->width),
116
- 'height'=>intval($_imageSize->height));
117
- if(!empty($imageSizes[$_imageSize->name]['crop'])) {
118
- $_new_meta['crop'] = $imageSizes[$_imageSize->name]['crop'];
119
  }
120
  $post_metadata['sizes'][$_imageSize->name] = $_new_meta;
 
 
121
  }
122
  }
123
 
@@ -126,7 +138,7 @@ class CptSaveThumbnail {
126
  wp_update_attachment_metadata( $obj->ID, $post_metadata);
127
 
128
  //generate result;
129
- $json_return['debug'] = $debug;
130
  if(!empty($_processing_error)) {
131
  //one or more errors happend when generating thumbnails
132
  $json_return['processingErrors'] = implode("\n",$_processing_error);
@@ -138,22 +150,41 @@ class CptSaveThumbnail {
138
  $json_return['success'] = time();//time for cache-breaker
139
  echo json_encode($json_return);
140
  } catch (Exception $e) {
141
- $json_return['debug'] = $debug;
142
  $json_return['error'] = $e->getMessage();
143
  echo json_encode($json_return);
144
  }
145
  die();
146
  }
147
 
 
 
 
 
 
 
 
 
 
 
 
148
  /**
149
  * @param object data of the new ImageSize the user want to crop
150
  * @param array all available ImageSizes
151
  * @return boolean true if the newImageSize is in the list of ImageSizes and dimensions are correct
152
  */
153
- function isImageSizeValid($_newImageSize,$imageSizes) {
154
- if(empty($imageSizes[$_newImageSize->name])) {
155
  return false;
156
  }
 
 
 
 
 
 
 
 
157
  //eventually we want to test some more later
158
  return true;
159
  }
@@ -169,11 +200,11 @@ class CptSaveThumbnail {
169
  function validation($selection,$obj,$sourceImgPath,$post_metadata) {
170
  global $cptSettings;
171
  if(!check_ajax_referer($cptSettings->getNonceBase(),'_ajax_nonce',false)) {
172
- throw new Exception(__("ERROR: Security Check failed (maybe a timeout - please try again).",CPT_LANG).$cptSettings->getNonceBase(), 1);
173
  }
174
 
175
  if(!isset($selection->x) || !isset($selection->y) || !isset($selection->x2) || !isset($selection->y2)) {
176
- throw new Exception(__('ERROR: Submitted data are not complete.',CPT_LANG), 1);
177
  }
178
  $selection->x = intval($selection->x);
179
  $selection->y = intval($selection->y);
@@ -181,7 +212,7 @@ class CptSaveThumbnail {
181
  $selection->y2 = intval($selection->y2);
182
 
183
  if($selection->x < 0 || $selection->y < 0) {
184
- throw new Exception(__('A cropping with this dimensions on these Image ist not possible.',CPT_LANG), 1);
185
  }
186
 
187
  /**
@@ -192,19 +223,19 @@ class CptSaveThumbnail {
192
  */
193
 
194
  if(empty($obj)) {
195
- throw new Exception(__('ERROR: Can`t find original Image in Database!',CPT_LANG), 1);
196
  }
197
  if(empty($sourceImgPath)) {
198
- throw new Exception(__('ERROR: Can`t find original Imagefile!',CPT_LANG), 1);
199
  }
200
  if(empty($post_metadata)) {
201
- throw new Exception(__('ERROR: Can`t find original Image-Metadata!',CPT_LANG), 1);
202
  }
203
  }
204
 
205
  /**
206
  * Generate the Filename (and path) of the thumbnail based on width and height the same way as wordpress do.
207
- * @see image_resize function in wp-includes/media.php
208
  * @param string Path to the original (full-size) file.
209
  * @param int width of the new image
210
  * @param int height of the new image
@@ -215,9 +246,6 @@ class CptSaveThumbnail {
215
  $dir = $info['dirname'];
216
  $ext = $info['extension'];
217
  $name = wp_basename($file, ".$ext");
218
-
219
- if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
220
- $dir = $_dest_path;
221
  $suffix = "{$w}x{$h}";
222
  $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
223
 
4
 
5
  class CptSaveThumbnail {
6
 
7
+ private $debug = array();
8
+
9
  /**
10
  * Handle-function called via ajax request.
11
  * Check and crop multiple Images. Update with wp_update_attachment_metadata if needed.
18
  */
19
  function saveThumbnail() {
20
  global $cptSettings;
 
21
  $json_return = array();
22
 
23
  try {
24
  /** get data **/
25
  $upload_dir = wp_upload_dir();
26
  $tmp_dir = $upload_dir['basedir']."/tmp/";
27
+ $options = $cptSettings->getOptions();
28
  //from $_REQUEST
29
  $selection = json_decode(stripcslashes($_REQUEST['selection']));
30
  $sourceImgData = json_decode(stripcslashes($_REQUEST['raw_values']));
31
  $targetImgData = json_decode(stripcslashes($_REQUEST['active_values']));
32
 
33
  //from DB
34
+ $dbImageSizes = $cptSettings->getImageSizes();
 
35
 
36
  $obj = get_post($sourceImgData->id);
37
  $sourceImgPath = get_attached_file( $obj->ID );
53
  $_changed_image_format = false;
54
  $_processing_error = array();
55
  foreach($targetImgData as $_imageSize) {
56
+ $this->addDebug('submitted image-data');
57
+ $this->addDebug(print_r($_imageSize,true));
58
  $_delete_old_file = '';
59
+ if(!$this->isImageSizeValid($_imageSize,$dbImageSizes)) {
60
+ $this->addDebug("Image Size not valid.");
61
  continue;
62
  }
63
  if(empty($post_metadata['sizes'][$_imageSize->name])) {
77
  $_filepath = $this->generateFilename($sourceImgPath, $_imageSize->width, $_imageSize->height);
78
  $_filepath_info = pathinfo($_filepath);
79
  $_tmp_filepath = $tmp_dir.$_filepath_info['basename'];
80
+ $this->addDebug("filename:".$_filepath);
81
+
82
+
83
+ $crop_width = $_imageSize->width;
84
+ $crop_height = $_imageSize->height;
85
+ if(!$_imageSize->crop || $_imageSize->width==0 || $_imageSize->height==0) {
86
+ //handle images with no crop
87
+ $crop_width = $selection->x2 - $selection->x;
88
+ $crop_height = $selection->y2 - $selection->y;
89
+ }
90
 
91
  $result = wp_crop_image( // * @return string|WP_Error|false New filepath on success, WP_Error or false on failure.
92
  intval($sourceImgData->id), // * @param string|int $src The source file or Attachment ID.
94
  $selection->y, // * @param int $src_y The start y position to crop from.
95
  $selection->x2 - $selection->x, // * @param int $src_w The width to crop.
96
  $selection->y2 - $selection->y, // * @param int $src_h The height to crop.
97
+ $crop_width, // * @param int $dst_w The destination width.
98
+ $crop_height, // * @param int $dst_h The destination height.
99
+ false, // * @param int $src_abs Optional. If the source crop points are absolute.
100
  $_tmp_filepath // * @param string $dst_file Optional. The destination file to write to.
101
  );
 
102
 
103
  $_error = false;
104
  if(empty($result)) {
105
+ $_processing_error[] = sprintf(__('Cant generate filesize "%s".',CROP_THUMBS_LANG),$_imageSize->name);
106
  $_error = true;
107
  } else {
108
  if(!empty($_delete_old_file)) {
109
  @unlink($_filepath_info['dirname'].'/'.$_delete_old_file);
110
  }
111
  if(!@copy($result,$_filepath)) {
112
+ $_processing_error[] = sprintf(__('Cant copy temporary file to media-library.',CROP_THUMBS_LANG));
113
  $_error = true;
114
  }
115
  if(!@unlink($result)) {
116
+ $_processing_error[] = sprintf(__('Cant delete temporary file.',CROP_THUMBS_LANG));
117
  $_error = true;
118
  }
119
  }
122
  //update metadata --> otherwise new sizes will not be updated
123
  $_new_meta = array(
124
  'file'=>$_filepath_info['basename'],
125
+ 'width'=>intval($crop_width),
126
+ 'height'=>intval($crop_height));
127
+ if(!empty($dbImageSizes[$_imageSize->name]['crop'])) {
128
+ $_new_meta['crop'] = $dbImageSizes[$_imageSize->name]['crop'];
129
  }
130
  $post_metadata['sizes'][$_imageSize->name] = $_new_meta;
131
+ } else {
132
+ $this->addDebug('error on '.$_filepath_info['basename']);
133
  }
134
  }
135
 
138
  wp_update_attachment_metadata( $obj->ID, $post_metadata);
139
 
140
  //generate result;
141
+ $json_return['debug'] = $this->getDebugOutput($options);
142
  if(!empty($_processing_error)) {
143
  //one or more errors happend when generating thumbnails
144
  $json_return['processingErrors'] = implode("\n",$_processing_error);
150
  $json_return['success'] = time();//time for cache-breaker
151
  echo json_encode($json_return);
152
  } catch (Exception $e) {
153
+ $json_return['debug'] = $this->getDebugOutput($options);
154
  $json_return['error'] = $e->getMessage();
155
  echo json_encode($json_return);
156
  }
157
  die();
158
  }
159
 
160
+ private function addDebug($text) {
161
+ $this->debug[] = $text;
162
+ }
163
+
164
+ private function getDebugOutput($options) {
165
+ if(!empty($this->debug)) {
166
+ return join("\n",$this->debug);
167
+ }
168
+ return '';
169
+ }
170
+
171
  /**
172
  * @param object data of the new ImageSize the user want to crop
173
  * @param array all available ImageSizes
174
  * @return boolean true if the newImageSize is in the list of ImageSizes and dimensions are correct
175
  */
176
+ function isImageSizeValid(&$submitted,$dbData) {
177
+ if(empty($submitted->name)) {
178
  return false;
179
  }
180
+ if(empty($dbData[$submitted->name])) {
181
+ return false;
182
+ }
183
+
184
+ //restore the default data just to make sure nothing is compromited
185
+ $submitted->crop = empty($dbData[$submitted->name]['crop']) ? 0 : 1;
186
+ $submitted->width = $dbData[$submitted->name]['width'];
187
+ $submitted->height = $dbData[$submitted->name]['height'];
188
  //eventually we want to test some more later
189
  return true;
190
  }
200
  function validation($selection,$obj,$sourceImgPath,$post_metadata) {
201
  global $cptSettings;
202
  if(!check_ajax_referer($cptSettings->getNonceBase(),'_ajax_nonce',false)) {
203
+ throw new Exception(__("ERROR: Security Check failed (maybe a timeout - please try again).",CROP_THUMBS_LANG), 1);
204
  }
205
 
206
  if(!isset($selection->x) || !isset($selection->y) || !isset($selection->x2) || !isset($selection->y2)) {
207
+ throw new Exception(__('ERROR: Submitted data are not complete.',CROP_THUMBS_LANG), 1);
208
  }
209
  $selection->x = intval($selection->x);
210
  $selection->y = intval($selection->y);
212
  $selection->y2 = intval($selection->y2);
213
 
214
  if($selection->x < 0 || $selection->y < 0) {
215
+ throw new Exception(__('A cropping with this dimensions on these Image ist not possible.',CROP_THUMBS_LANG), 1);
216
  }
217
 
218
  /**
223
  */
224
 
225
  if(empty($obj)) {
226
+ throw new Exception(__('ERROR: Can`t find original Image in Database!',CROP_THUMBS_LANG), 1);
227
  }
228
  if(empty($sourceImgPath)) {
229
+ throw new Exception(__('ERROR: Can`t find original Imagefile!',CROP_THUMBS_LANG), 1);
230
  }
231
  if(empty($post_metadata)) {
232
+ throw new Exception(__('ERROR: Can`t find original Image-Metadata!',CROP_THUMBS_LANG), 1);
233
  }
234
  }
235
 
236
  /**
237
  * Generate the Filename (and path) of the thumbnail based on width and height the same way as wordpress do.
238
+ * @see generate_filename in wp-includes/class-wp-image-editor.php
239
  * @param string Path to the original (full-size) file.
240
  * @param int width of the new image
241
  * @param int height of the new image
246
  $dir = $info['dirname'];
247
  $ext = $info['extension'];
248
  $name = wp_basename($file, ".$ext");
 
 
 
249
  $suffix = "{$w}x{$h}";
250
  $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
251
 
functions/settings.php CHANGED
@@ -2,74 +2,100 @@
2
  class CropThumbnailsSettings {
3
  private $uniqeSettingsId = 'cpt-settings';
4
  private $optionsKey = 'crop-post-thumbs';
 
5
  private $standardSizes = array('thumbnail','medium','large');
6
 
7
  function __construct() {
8
  add_action('admin_menu', array($this,'addOptionsPage'));
9
  if(is_admin()) {
10
  add_filter('plugin_action_links', array($this,'addSettingsLinkToPluginPage'), 10, 2);
 
 
 
 
 
 
 
11
  }
12
  }
13
 
14
  function addSettingsLinkToPluginPage($links, $file) {
15
  if ($file === 'crop-thumbnails/crop-thumbnails.php'){
16
- $settings_link = '<a href="options-general.php?page=page-cpt" title="">'.__('Settings',CPT_LANG).'</a>';
17
  array_unshift( $links, $settings_link );
18
  }
19
  return $links;
20
  }
21
 
22
  function addOptionsPage() {
23
- add_options_page(__('Crop Post Thumbnail Page',CPT_LANG), 'Crop-Thumbnails', 'manage_options', 'page-cpt', array($this,'optionsPage'));
24
  add_action('admin_init', array($this,'settingsInitialisation'));
25
  }
26
 
27
  function optionsPage() { ?>
28
  <div class="wrap">
29
  <div id="icon-options-general" class="icon32"><br /></div>
30
- <h2>Crop-Thumbnails <?php esc_attr_e('Settings',CPT_LANG); ?></h2>
31
  <form action="options.php" method="post">
32
- <?php settings_fields($this->uniqeSettingsId); ?>
33
- <?php do_settings_sections('page1'); ?>
34
-
35
- <input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes',CPT_LANG); ?>" class="button-primary" />
 
 
36
  </form>
37
 
38
- <div style="border:1px solid #298CBA; border-radius:3px; background-color:#f6f6f6; max-width:30em; padding:0 0.5em; margin:2em 0; text-align:center;">
39
- <h3><?php _e('Support the plugin-author',CPT_LANG) ?></h3>
40
- <p><?php _e('You can support the plugin-author <br />(and let him know you love this plugin) <br />by donating via Paypal. Thanks a lot!',CPT_LANG); ?></p>
41
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
42
- <input type="hidden" name="cmd" value="_donations">
43
- <input type="hidden" name="business" value="volkmar.kantor@gmx.de">
44
- <input type="hidden" name="lc" value="DE">
45
- <input type="hidden" name="item_name" value="Volkmar Kantor - totalmedial.de">
46
- <input type="hidden" name="item_number" value="crop-thumbnails">
47
- <input type="hidden" name="no_note" value="0">
48
- <input type="hidden" name="currency_code" value="EUR">
49
- <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHostedGuest">
50
- <input type="image" src="https://www.paypalobjects.com/de_DE/DE/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Jetzt einfach, schnell und sicher online bezahlen – mit PayPal.">
51
- <img alt="" border="0" src="https://www.paypalobjects.com/de_DE/i/scr/pixel.gif" width="1" height="1">
52
- </form>
53
- </div>
54
  </div>
55
  <?php
56
  }
57
 
58
  function settingsInitialisation(){
59
  register_setting( $this->uniqeSettingsId, $this->optionsKey, array($this,'validateSettings') );
60
- add_settings_section('choose_sizes_section', __('Sizes and Posttypes',CPT_LANG), array($this,'showSectionDescriptionChooseSizes'), 'page1');
61
- add_settings_field('sizes', __('Choose the image-sizes you want to hide. Choose a post-type to prevent any use of the plugin for these entries.',CPT_LANG), array($this,'chooseSizeInputFields'), 'page1', 'choose_sizes_section');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
 
64
- function showSectionDescriptionChooseSizes() {?>
65
  <p>
66
- <?php _e('Crop-Thumbnails is created to make cropping easy for the user. Often times the user only need to crop one, in dependence of the post-type. But the system will create also all other sizes. So, here you can select for what post-type what sizes should be visible in the plugin interface.',CPT_LANG) ?>
67
- <br /><strong><?php _e('Crop-Thumbnails will only show croped images - sizes with no crop will always be hidden.',CPT_LANG); ?></strong>
68
  </p>
69
  <?php
70
  }
 
 
71
 
72
- function chooseSizeInputFields() {
73
  //get all the data
74
  $options = get_option($this->optionsKey);
75
  #echo '<pre>'.print_r($options,true).'</pre>';
@@ -80,8 +106,8 @@ class CropThumbnailsSettings {
80
  echo '<ul>';
81
  foreach($post_types as $post_type=>$value) { ?>
82
  <li>
83
- <label for="cpt-<?php echo $post_type; ?>">
84
- <input id="cpt-<?php echo $post_type;?>" type="checkbox" name="<?php echo $this->optionsKey; ?>[hide_post_type][<?php echo $post_type;?>]" value="1" <?php checked(isset($options['hide_post_type'][$post_type]),true); ?> />
85
  <strong><?php echo $value->labels->name; ?></strong>
86
  </label>
87
  <ul style="margin:1em;">
@@ -89,14 +115,14 @@ class CropThumbnailsSettings {
89
 
90
  foreach($image_sizes as $thumb_name => $data) :
91
  $_checked = false;
92
- if(is_array($options['hide_size']) && !empty($options['hide_size'][$post_type][$thumb_name])) {
93
  $_checked = true;
94
  }
95
  if($data['crop']=='1') :
96
  ?>
97
  <li>
98
- <label for="cpt-<?php echo $post_type;?>-<?php echo $thumb_name;?>">
99
- <input id="cpt-<?php echo $post_type;?>-<?php echo $thumb_name;?>" type="checkbox" name="<?php echo $this->optionsKey; ?>[hide_size][<?php echo $post_type; ?>][<?php echo $thumb_name; ?>]" value="1" <?php echo checked($_checked); ?> />
100
  <?php echo $thumb_name;?> - <?php echo $data['width'];?>x<?php echo $data['height'];?> <?php /* echo ($data['crop'] == '1' ? '(cropped)' : '') */?>
101
  </label>
102
  </li>
@@ -110,6 +136,83 @@ class CropThumbnailsSettings {
110
  echo '</ul>';
111
  }
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
  /**
115
  * get the post types and delete some prebuild post types that we dont need
@@ -165,33 +268,6 @@ class CropThumbnailsSettings {
165
  return $sizes;
166
  }
167
 
168
- function validateSettings($input) {
169
- $sizes = $this->getImageSizes();
170
-
171
- $post_types = $this->getPostTypes();
172
-
173
- $storeInDb = array();
174
- //check input[hide_post_type] --> are the post_types real there
175
- foreach($input['hide_post_type'] as $_post_type_name=>$value) {
176
- if(isset($post_types[$_post_type_name])) {
177
- $storeInDb['hide_post_type'][$_post_type_name] = '1';
178
- }
179
- }
180
-
181
- //check $input[sizes] --> are post_types correct, are sizes real there
182
- foreach($input['hide_size'] as $_post_type_name=>$size_type) {
183
- if(isset($post_types[$_post_type_name])) {
184
- foreach($size_type as $_size_name=>$value) {
185
- if(isset($sizes[$_size_name])) {
186
- $storeInDb['hide_size'][$_post_type_name][$_size_name] = '1';
187
- }
188
- }
189
- }
190
- }
191
-
192
- return $storeInDb;
193
- }
194
-
195
  function getOptions() {
196
  return get_option($this->optionsKey);
197
  }
2
  class CropThumbnailsSettings {
3
  private $uniqeSettingsId = 'cpt-settings';
4
  private $optionsKey = 'crop-post-thumbs';
5
+ private $cssPrefix = 'cpt_settings_';
6
  private $standardSizes = array('thumbnail','medium','large');
7
 
8
  function __construct() {
9
  add_action('admin_menu', array($this,'addOptionsPage'));
10
  if(is_admin()) {
11
  add_filter('plugin_action_links', array($this,'addSettingsLinkToPluginPage'), 10, 2);
12
+ add_action('admin_head', array($this,'optionsPageStyle'));
13
+ }
14
+ }
15
+
16
+ function optionsPageStyle() {
17
+ if(!empty($_REQUEST['page']) && $_REQUEST['page']=='page-cpt') {
18
+ wp_enqueue_style('crop-thumbnails-options-style',plugins_url('css/options.css',dirname(__FILE__)));
19
  }
20
  }
21
 
22
  function addSettingsLinkToPluginPage($links, $file) {
23
  if ($file === 'crop-thumbnails/crop-thumbnails.php'){
24
+ $settings_link = '<a href="options-general.php?page=page-cpt" title="">'.__('Settings',CROP_THUMBS_LANG).'</a>';
25
  array_unshift( $links, $settings_link );
26
  }
27
  return $links;
28
  }
29
 
30
  function addOptionsPage() {
31
+ add_options_page(__('Crop Post Thumbnail Page',CROP_THUMBS_LANG), 'Crop-Thumbnails', 'manage_options', 'page-cpt', array($this,'optionsPage'));
32
  add_action('admin_init', array($this,'settingsInitialisation'));
33
  }
34
 
35
  function optionsPage() { ?>
36
  <div class="wrap">
37
  <div id="icon-options-general" class="icon32"><br /></div>
38
+ <h2>Crop-Thumbnails <?php esc_attr_e('Settings',CROP_THUMBS_LANG); ?></h2>
39
  <form action="options.php" method="post">
40
+ <?php settings_fields($this->uniqeSettingsId); ?>
41
+ <?php do_settings_sections('page1'); ?>
42
+
43
+ <div class="<?php echo $this->cssPrefix ?>submit">
44
+ <input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes',CROP_THUMBS_LANG); ?>" class="button-primary" />
45
+ </div>
46
  </form>
47
 
48
+ <div class="<?php echo $this->cssPrefix; ?>paypal">
49
+ <h3><?php _e('Support the plugin-author',CROP_THUMBS_LANG) ?></h3>
50
+ <p><?php _e('You can support the plugin-author <br />(and let him know you love this plugin) <br />by donating via Paypal. Thanks a lot!',CROP_THUMBS_LANG); ?></p>
51
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
52
+ <input type="hidden" name="cmd" value="_donations">
53
+ <input type="hidden" name="business" value="volkmar.kantor@gmx.de">
54
+ <input type="hidden" name="lc" value="DE">
55
+ <input type="hidden" name="item_name" value="Volkmar Kantor - totalmedial.de">
56
+ <input type="hidden" name="item_number" value="crop-thumbnails">
57
+ <input type="hidden" name="no_note" value="0">
58
+ <input type="hidden" name="currency_code" value="EUR">
59
+ <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHostedGuest">
60
+ <input type="image" src="https://www.paypalobjects.com/de_DE/DE/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Jetzt einfach, schnell und sicher online bezahlen – mit PayPal.">
61
+ <img alt="" border="0" src="https://www.paypalobjects.com/de_DE/i/scr/pixel.gif" width="1" height="1">
62
+ </form>
63
+ </div>
64
  </div>
65
  <?php
66
  }
67
 
68
  function settingsInitialisation(){
69
  register_setting( $this->uniqeSettingsId, $this->optionsKey, array($this,'validateSettings') );
70
+
71
+ $_sectionID = 'choose_sizes_section';
72
+ add_settings_section($_sectionID, __('Sizes and Posttypes',CROP_THUMBS_LANG), array($this,'sectionDescriptionChooseSizes'), 'page1');
73
+ add_settings_field('sizes', __('Choose the image-sizes you want to hide. Choose a post-type to prevent any use of the plugin for these entries.',CROP_THUMBS_LANG), array($this,'callback_choose_size'), 'page1', $_sectionID);
74
+ /*
75
+ $_sectionID = 'experimental';
76
+ add_settings_section($_sectionID, __('Experimental Settings',CROP_THUMBS_LANG), array($this,'emptySectionDescription'), 'page1');
77
+ $_tmpID = 'allow_non_cropped';
78
+ add_settings_field($_tmpID, __('Allow non cropped image-sizes.',CROP_THUMBS_LANG), array($this,'callback_'.$_tmpID), 'page1', $_sectionID, array( 'label_for' => $this->cssPrefix.$_tmpID ));
79
+ */
80
+ $_sectionID = 'developer';
81
+ add_settings_section($_sectionID, __('Developer Settings',CROP_THUMBS_LANG), array($this,'emptySectionDescription'), 'page1');
82
+ $_tmpID = 'debug_js';
83
+ add_settings_field($_tmpID, __('Enable JS-Debug.',CROP_THUMBS_LANG), array($this,'callback_'.$_tmpID), 'page1', $_sectionID, array( 'label_for' => $this->cssPrefix.$_tmpID ));
84
+ $_tmpID = 'debug_data';
85
+ add_settings_field($_tmpID, __('Enable Data-Debug.',CROP_THUMBS_LANG), array($this,'callback_'.$_tmpID), 'page1', $_sectionID, array( 'label_for' => $this->cssPrefix.$_tmpID ));
86
  }
87
 
88
+ function sectionDescriptionChooseSizes() {?>
89
  <p>
90
+ <?php _e('Crop-Thumbnails is created to make cropping easy for the user. Often times the user only need to crop one, in dependence of the post-type. But the system will create also all other sizes. So, here you can select for what post-type what sizes should be visible in the plugin interface.',CROP_THUMBS_LANG) ?>
91
+ <br /><strong><?php _e('Crop-Thumbnails will only show croped images - sizes with no crop will always be hidden.',CROP_THUMBS_LANG); ?></strong>
92
  </p>
93
  <?php
94
  }
95
+
96
+ function emptySectionDescription() {/*empty*/ }
97
 
98
+ function callback_choose_size() {
99
  //get all the data
100
  $options = get_option($this->optionsKey);
101
  #echo '<pre>'.print_r($options,true).'</pre>';
106
  echo '<ul>';
107
  foreach($post_types as $post_type=>$value) { ?>
108
  <li>
109
+ <label for="<?php echo $this->cssPrefix.$post_type; ?>">
110
+ <input id="<?php echo $this->cssPrefix.$post_type;?>" type="checkbox" name="<?php echo $this->optionsKey; ?>[hide_post_type][<?php echo $post_type;?>]" value="1" <?php checked(isset($options['hide_post_type'][$post_type]),true); ?> />
111
  <strong><?php echo $value->labels->name; ?></strong>
112
  </label>
113
  <ul style="margin:1em;">
115
 
116
  foreach($image_sizes as $thumb_name => $data) :
117
  $_checked = false;
118
+ if(!empty($options['hide_size']) && is_array($options['hide_size']) && !empty($options['hide_size'][$post_type][$thumb_name])) {
119
  $_checked = true;
120
  }
121
  if($data['crop']=='1') :
122
  ?>
123
  <li>
124
+ <label for="<?php echo $this->cssPrefix.$post_type;?>-<?php echo $thumb_name;?>">
125
+ <input id="<?php echo $this->cssPrefix.$post_type;?>-<?php echo $thumb_name;?>" type="checkbox" name="<?php echo $this->optionsKey; ?>[hide_size][<?php echo $post_type; ?>][<?php echo $thumb_name; ?>]" value="1" <?php echo checked($_checked); ?> />
126
  <?php echo $thumb_name;?> - <?php echo $data['width'];?>x<?php echo $data['height'];?> <?php /* echo ($data['crop'] == '1' ? '(cropped)' : '') */?>
127
  </label>
128
  </li>
136
  echo '</ul>';
137
  }
138
 
139
+ function callback_allow_non_cropped() {
140
+ $options = get_option($this->optionsKey);
141
+ $_id = 'allow_non_cropped';
142
+ if(empty($options[$_id])) { $options[$_id] = ''; }
143
+ echo '<input name="'.$this->optionsKey.'['.$_id.']" id="'.$this->cssPrefix.$_id.'" type="checkbox" value="1" ' . checked( 1, $options[$_id], false) . ' />';
144
+ ?>
145
+ <div class="info">
146
+ <?php _e('ATTENTION: be aware that you can break things, when you activate this. When activated your are able to cut those images to a spezific dimension that are not cropped. The name of the image will not change. You should be extra carefull when:',CROP_THUMBS_LANG) ?>
147
+ <ul>
148
+ <li><?php _e('you had inserted the image before on any page or post. (There may be height and width stored directly in the page-content.)',CROP_THUMBS_LANG); ?></li>
149
+ <li><?php _e('you use a plugin that expect the original image size. (The original image-size is also "stored" in the filename.)',CROP_THUMBS_LANG); ?></li>
150
+ </ul>
151
+ <p><?php _e('The "full" image-size will never be cropped, otherwise you are not able to restore any image-size.',CROP_THUMBS_LANG); ?></p>
152
+ </div>
153
+ <?php
154
+ }
155
+
156
+ function callback_debug_js() {
157
+ $options = get_option($this->optionsKey);
158
+ $_id = 'debug_js';
159
+ if(empty($options[$_id])) { $options[$_id] = ''; }
160
+ echo '<input name="'.$this->optionsKey.'['.$_id.']" id="'.$this->cssPrefix.$_id.'" type="checkbox" value="1" ' . checked( 1, $options[$_id], false) . ' />';
161
+ }
162
+
163
+ function callback_debug_data() {
164
+ $options = get_option($this->optionsKey);
165
+ $_id = 'debug_data';
166
+ if(empty($options[$_id])) { $options[$_id] = ''; }
167
+ echo '<input name="'.$this->optionsKey.'['.$_id.']" id="'.$this->cssPrefix.$_id.'" type="checkbox" value="1" ' . checked( 1, $options[$_id], false ) . ' />';
168
+ }
169
+
170
+ function validateSettings($input) {
171
+ $sizes = $this->getImageSizes();
172
+
173
+ $post_types = $this->getPostTypes();
174
+
175
+ $storeInDb = array();
176
+ //check input[hide_post_type] --> are the post_types real there
177
+ foreach($input['hide_post_type'] as $_post_type_name=>$value) {
178
+ if(isset($post_types[$_post_type_name])) {
179
+ $storeInDb['hide_post_type'][$_post_type_name] = '1';
180
+ }
181
+ }
182
+
183
+ //check $input[sizes] --> are post_types correct, are sizes real there
184
+ foreach($input['hide_size'] as $_post_type_name=>$size_type) {
185
+ if(isset($post_types[$_post_type_name])) {
186
+ foreach($size_type as $_size_name=>$value) {
187
+ if(isset($sizes[$_size_name])) {
188
+ $storeInDb['hide_size'][$_post_type_name][$_size_name] = '1';
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ /* Experimental Section */
195
+ $_tmpID = 'allow_non_cropped';
196
+ if(!empty($input[$_tmpID])) {
197
+ $storeInDb[$_tmpID] = 1;
198
+ }
199
+
200
+ /* Advanced Section */
201
+ $_tmpID = 'debug_js';
202
+ if(!empty($input[$_tmpID])) {
203
+ $storeInDb[$_tmpID] = 1;
204
+ }
205
+
206
+ $_tmpID = 'debug_data';
207
+ if(!empty($input[$_tmpID])) {
208
+ $storeInDb[$_tmpID] = 1;
209
+ }
210
+
211
+ return $storeInDb;
212
+ }
213
+
214
+ /* helper functions **********************************************************************************************/
215
+
216
 
217
  /**
218
  * get the post types and delete some prebuild post types that we dont need
268
  return $sizes;
269
  }
270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  function getOptions() {
272
  return get_option($this->optionsKey);
273
  }
js/cpt-crop.js CHANGED
@@ -55,6 +55,12 @@ jQuery(document).ready(function($) {
55
  }
56
  });
57
 
 
 
 
 
 
 
58
  /********************************/
59
  function doProcessing(active,cropping) {
60
  /*console.log('doProcessing');*/
@@ -67,8 +73,6 @@ jQuery(document).ready(function($) {
67
  $('.mainWindow').hide();
68
  $('.waitingWindow').show();
69
 
70
- /*console.log('selection',cropping.api.tellSelect());*/
71
-
72
  $.ajax({
73
  data:{
74
  action: 'cptSaveThumbnail',
@@ -83,19 +87,28 @@ jQuery(document).ready(function($) {
83
  $('.waitingWindow').hide();
84
  },
85
  success : function( response ) {
86
- var result = JSON.parse(response);
87
- /*console.log(result);*/
88
- if(typeof result.success == "number") {
89
 
90
- if(result.changed_image_format) {
91
- window.location.reload();
 
 
 
 
 
 
 
 
 
92
  } else {
93
- doCacheBreaker(result.success);
 
94
  }
95
- } else {
96
- //saving fail
97
- alert(result.error);
98
  }
 
99
  }
100
  });
101
  }
@@ -132,51 +145,91 @@ jQuery(document).ready(function($) {
132
  }
133
  }
134
 
135
- function activateArea(c,li) {
136
  deactivateArea(c);
137
  var allActiveThumbs = $('.thumbnail-list li.active img');
138
  var largestWidth = 0;
139
  var largestHeight = 0;
140
  var ratio = 0;
 
 
 
 
141
  allActiveThumbs.each(function() {
 
142
  if(ratio === 0) {
143
- ratio = $(this).data('values').ratio;//initial
144
  }
145
- if(ratio != $(this).data('values').ratio) {
146
- alert(cpt_lang['bug']);
 
147
  }
148
 
149
  //we only need to check in one dimension, cause per definition all selected images have to use the same ratio
150
- if($(this).data('values').width > largestWidth) {
151
- largestWidth = $(this).data('values').width;
152
- largestHeight = $(this).data('values').height;
 
 
 
 
 
 
 
153
  }
154
  });
155
 
 
 
 
 
 
 
156
 
157
- var scale = c.img.width() / largestWidth;
158
  var preSelect = [ 0, 0, Math.round(scale*c.img.width()), Math.round(scale*c.img.height()) ];
159
  var minSize = [ largestWidth, largestHeight ];
 
160
 
161
-
162
-
163
  var options = {}
164
  options.boxWidth = c.img.width();
165
  options.boxHeight = c.img.height();
166
  options.trueSize = [cropping.img.data('values').width,c.img.data('values').height];
167
  options.aspectRatio = ratio;
168
  options.setSelect = preSelect;
 
169
  if(largestWidth>cropping.img.data('values').width || largestHeight>cropping.img.data('values').height) {
170
  alert(cpt_lang['warningOriginalToSmall']);
171
- if(ratio>=0) {
172
- options.setSelect = [ 0, 0, cropping.img.data('values').width, Math.round(scale*c.img.height()) ];
173
- } else {
174
- options.setSelect = [ 0, 0, Math.round(scale*c.img.width()) , cropping.img.data('values').height];
175
- }
176
  } else {
177
  options.minSize = minSize;
178
  }
179
- //console.log('options',options);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
  c.api = $.Jcrop(c.img, options);
182
  }
55
  }
56
  });
57
 
58
+
59
+ $('.cpt-debug .cpt-debug-handle').click(function(e) {
60
+ e.preventDefault();
61
+ $('.cpt-debug').toggleClass('closed');
62
+ });
63
+
64
  /********************************/
65
  function doProcessing(active,cropping) {
66
  /*console.log('doProcessing');*/
73
  $('.mainWindow').hide();
74
  $('.waitingWindow').show();
75
 
 
 
76
  $.ajax({
77
  data:{
78
  action: 'cptSaveThumbnail',
87
  $('.waitingWindow').hide();
88
  },
89
  success : function( response ) {
90
+ try {
91
+ var result = JSON.parse(response);
 
92
 
93
+ if(cpt_debug_js) {
94
+ console.log('Save Function Debug',result.debug);
95
+ }
96
+
97
+ if(typeof result.success == "number") {
98
+
99
+ if(result.changed_image_format) {
100
+ window.location.reload();
101
+ } else {
102
+ doCacheBreaker(result.success);
103
+ }
104
  } else {
105
+ //saving fail
106
+ alert(result.error);
107
  }
108
+ } catch(e) {
109
+ alert(e.message+"\n"+response);
 
110
  }
111
+
112
  }
113
  });
114
  }
145
  }
146
  }
147
 
148
+ function activateArea(c) {
149
  deactivateArea(c);
150
  var allActiveThumbs = $('.thumbnail-list li.active img');
151
  var largestWidth = 0;
152
  var largestHeight = 0;
153
  var ratio = 0;
154
+ var crop = true;
155
+
156
+
157
+ //get the options
158
  allActiveThumbs.each(function() {
159
+ var img_data = $(this).data('values');
160
  if(ratio === 0) {
161
+ ratio = img_data.ratio;//initial
162
  }
163
+ if(ratio != img_data.ratio) {
164
+ //alert(cpt_lang['bug']);
165
+ //TODO: test if this is still needed
166
  }
167
 
168
  //we only need to check in one dimension, cause per definition all selected images have to use the same ratio
169
+ if(img_data.width > largestWidth) {
170
+ largestWidth = img_data.width;
171
+ largestHeight = img_data.height;
172
+ }
173
+
174
+ //crop also has to be the same on all selected images
175
+ if(img_data.crop==1) {
176
+ crop = true;
177
+ } else {
178
+ crop = false;
179
  }
180
  });
181
 
182
+ var scale = 0;
183
+ if(ratio>=0) {
184
+ scale = c.img.data('values').height / largestHeight;
185
+ } else {
186
+ scale = c.img.data('values').width / largestWidth;
187
+ }
188
 
 
189
  var preSelect = [ 0, 0, Math.round(scale*c.img.width()), Math.round(scale*c.img.height()) ];
190
  var minSize = [ largestWidth, largestHeight ];
191
+ // END get the options
192
 
193
+ //set the options
 
194
  var options = {}
195
  options.boxWidth = c.img.width();
196
  options.boxHeight = c.img.height();
197
  options.trueSize = [cropping.img.data('values').width,c.img.data('values').height];
198
  options.aspectRatio = ratio;
199
  options.setSelect = preSelect;
200
+
201
  if(largestWidth>cropping.img.data('values').width || largestHeight>cropping.img.data('values').height) {
202
  alert(cpt_lang['warningOriginalToSmall']);
 
 
 
 
 
203
  } else {
204
  options.minSize = minSize;
205
  }
206
+
207
+ //correct some options
208
+ if(ratio>=0) {
209
+ //add a offset to move the selection in the middle
210
+ var crop_offset = (cropping.img.data('values').width - scale * largestWidth ) / 2;
211
+ options.setSelect = [ crop_offset, 0, cropping.img.data('values').width, Math.round(scale*c.img.height()) ];
212
+ } else {
213
+ //no offset cause in most cases the the selection is needed in the upper corner (human portrait)
214
+ options.setSelect = [ 0, 0, Math.round(scale*c.img.width()) , cropping.img.data('values').height];
215
+ }
216
+
217
+ if(scale===Infinity) {
218
+ options.setSelect = [ 0, 0, Math.round(scale*c.img.width()) , cropping.img.data('values').height];
219
+ }
220
+
221
+ //free scaling
222
+ if(!crop) {
223
+ options.aspectRatio = false;
224
+ options.setSelect = [0,0,cropping.img.data('values').width,cropping.img.data('values').height];
225
+ console.log('free scaling');
226
+ }
227
+
228
+ //debug
229
+ if(cpt_debug_js) {
230
+ console.log('choosed image - data',c.img.data('values'));
231
+ console.log('JCrop - options',options);
232
+ }
233
 
234
  c.api = $.Jcrop(c.img, options);
235
  }
js/jcrop/css/Jcrop.gif ADDED
Binary file
js/jcrop/css/jquery.Jcrop.min.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* jquery.Jcrop.min.css v0.9.12 (build:20130126) */
2
+ .jcrop-holder{direction:ltr;text-align:left;}
3
+ .jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif);font-size:0;position:absolute;}
4
+ .jcrop-vline{height:100%;width:1px!important;}
5
+ .jcrop-vline.right{right:0;}
6
+ .jcrop-hline{height:1px!important;width:100%;}
7
+ .jcrop-hline.bottom{bottom:0;}
8
+ .jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
9
+ .jcrop-handle{background-color:#333;border:1px #EEE solid;font-size:1px;height:7px;width:7px;}
10
+ .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
11
+ .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
12
+ .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
13
+ .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
14
+ .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
15
+ .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
16
+ .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
17
+ .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
18
+ .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
19
+ .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
20
+ .jcrop-dragbar.ord-n{margin-top:-4px;}
21
+ .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
22
+ .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
23
+ .jcrop-dragbar.ord-w{margin-left:-4px;}
24
+ .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.70!important;}
25
+ .jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
26
+ .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important;}
27
+ .jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
28
+ .solid-line .jcrop-vline,.solid-line .jcrop-hline{background:#FFF;}
29
+ .jcrop-holder img,img.jcrop-preview{max-width:none;}
js/jcrop/js/jquery.Jcrop.min.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * jquery.Jcrop.min.js v0.9.12 (build:20130202)
3
+ * jQuery Image Cropping Plugin - released under MIT License
4
+ * Copyright (c) 2008-2013 Tapmodo Interactive LLC
5
+ * https://github.com/tapmodo/Jcrop
6
+ */
7
+ (function(a){a.Jcrop=function(b,c){function i(a){return Math.round(a)+"px"}function j(a){return d.baseClass+"-"+a}function k(){return a.fx.step.hasOwnProperty("backgroundColor")}function l(b){var c=a(b).offset();return[c.left,c.top]}function m(a){return[a.pageX-e[0],a.pageY-e[1]]}function n(b){typeof b!="object"&&(b={}),d=a.extend(d,b),a.each(["onChange","onSelect","onRelease","onDblClick"],function(a,b){typeof d[b]!="function"&&(d[b]=function(){})})}function o(a,b,c){e=l(D),bc.setCursor(a==="move"?a:a+"-resize");if(a==="move")return bc.activateHandlers(q(b),v,c);var d=_.getFixed(),f=r(a),g=_.getCorner(r(f));_.setPressed(_.getCorner(f)),_.setCurrent(g),bc.activateHandlers(p(a,d),v,c)}function p(a,b){return function(c){if(!d.aspectRatio)switch(a){case"e":c[1]=b.y2;break;case"w":c[1]=b.y2;break;case"n":c[0]=b.x2;break;case"s":c[0]=b.x2}else switch(a){case"e":c[1]=b.y+1;break;case"w":c[1]=b.y+1;break;case"n":c[0]=b.x+1;break;case"s":c[0]=b.x+1}_.setCurrent(c),bb.update()}}function q(a){var b=a;return bd.watchKeys
8
+ (),function(a){_.moveOffset([a[0]-b[0],a[1]-b[1]]),b=a,bb.update()}}function r(a){switch(a){case"n":return"sw";case"s":return"nw";case"e":return"nw";case"w":return"ne";case"ne":return"sw";case"nw":return"se";case"se":return"nw";case"sw":return"ne"}}function s(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(b)),b.stopPropagation(),b.preventDefault(),!1)}}function t(a,b,c){var d=a.width(),e=a.height();d>b&&b>0&&(d=b,e=b/a.width()*a.height()),e>c&&c>0&&(e=c,d=c/a.height()*a.width()),T=a.width()/d,U=a.height()/e,a.width(d).height(e)}function u(a){return{x:a.x*T,y:a.y*U,x2:a.x2*T,y2:a.y2*U,w:a.w*T,h:a.h*U}}function v(a){var b=_.getFixed();b.w>d.minSelect[0]&&b.h>d.minSelect[1]?(bb.enableHandles(),bb.done()):bb.release(),bc.setCursor(d.allowSelect?"crosshair":"default")}function w(a){if(d.disabled)return!1;if(!d.allowSelect)return!1;W=!0,e=l(D),bb.disableHandles(),bc.setCursor("crosshair");var b=m(a);return _.setPressed(b),bb.update(),bc.activateHandlers(x,v,a.type.substring
9
+ (0,5)==="touch"),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("<div></div>").addClass(j("tracker"));return g&&b.css({opacity:0,backgroundColor:"white"}),b}function be(a){G.removeClass().addClass(j("holder")).addClass(a)}function bf(a,b){function t(){window.setTimeout(u,l)}var c=a[0]/T,e=a[1]/U,f=a[2]/T,g=a[3]/U;if(X)return;var h=_.flipCoords(c,e,f,g),i=_.getFixed(),j=[i.x,i.y,i.x2,i.y2],k=j,l=d.animationDelay,m=h[0]-j[0],n=h[1]-j[1],o=h[2]-j[2],p=h[3]-j[3],q=0,r=d.swingSpeed;c=k[0],e=k[1],f=k[2],g=k[3],bb.animMode(!0);var s,u=function(){return function(){q+=(100-q)/r,k[0]=Math.round(c+q/100*m),k[1]=Math.round(e+q/100*n),k[2]=Math.round(f+q/100*o),k[3]=Math.round(g+q/100*p),q>=99.8&&(q=100),q<100?(bh(k),t()):(bb.done(),bb.animMode(!1),typeof b=="function"&&b.call(bs))}}();t()}function bg(a){bh([a[0]/T,a[1]/U,a[2]/T,a[3]/U]),d.onSelect.call(bs,u(_.getFixed())),bb.enableHandles()}function bh(a){_.setPressed([a[0],a[1]]),_.setCurrent([a[2],
10
+ a[3]]),bb.update()}function bi(){return u(_.getFixed())}function bj(){return _.getFixed()}function bk(a){n(a),br()}function bl(){d.disabled=!0,bb.disableHandles(),bb.setCursor("default"),bc.setCursor("default")}function bm(){d.disabled=!1,br()}function bn(){bb.done(),bc.activateHandlers(null,null)}function bo(){G.remove(),A.show(),A.css("visibility","visible"),a(b).removeData("Jcrop")}function bp(a,b){bb.release(),bl();var c=new Image;c.onload=function(){var e=c.width,f=c.height,g=d.boxWidth,h=d.boxHeight;D.width(e).height(f),D.attr("src",a),H.attr("src",a),t(D,g,h),E=D.width(),F=D.height(),H.width(E).height(F),M.width(E+L*2).height(F+L*2),G.width(E).height(F),ba.resize(E,F),bm(),typeof b=="function"&&b.call(bs)},c.src=a}function bq(a,b,c){var e=b||d.bgColor;d.bgFade&&k()&&d.fadeTime&&!c?a.animate({backgroundColor:e},{queue:!1,duration:d.fadeTime}):a.css("backgroundColor",e)}function br(a){d.allowResize?a?bb.enableOnly():bb.enableHandles():bb.disableHandles(),bc.setCursor(d.allowSelect?"crosshair":"default"),bb
11
+ .setCursor(d.allowMove?"move":"default"),d.hasOwnProperty("trueSize")&&(T=d.trueSize[0]/E,U=d.trueSize[1]/F),d.hasOwnProperty("setSelect")&&(bg(d.setSelect),bb.done(),delete d.setSelect),ba.refresh(),d.bgColor!=N&&(bq(d.shade?ba.getShades():G,d.shade?d.shadeColor||d.bgColor:d.bgColor),N=d.bgColor),O!=d.bgOpacity&&(O=d.bgOpacity,d.shade?ba.refresh():bb.setBgOpacity(O)),P=d.maxSize[0]||0,Q=d.maxSize[1]||0,R=d.minSize[0]||0,S=d.minSize[1]||0,d.hasOwnProperty("outerImage")&&(D.attr("src",d.outerImage),delete d.outerImage),bb.refresh()}var d=a.extend({},a.Jcrop.defaults),e,f=navigator.userAgent.toLowerCase(),g=/msie/.test(f),h=/msie [1-6]\./.test(f);typeof b!="object"&&(b=a(b)[0]),typeof c!="object"&&(c={}),n(c);var z={border:"none",visibility:"visible",margin:0,padding:0,position:"absolute",top:0,left:0},A=a(b),B=!0;if(b.tagName=="IMG"){if(A[0].width!=0&&A[0].height!=0)A.width(A[0].width),A.height(A[0].height);else{var C=new Image;C.src=A[0].src,A.width(C.width),A.height(C.height)}var D=A.clone().removeAttr("id").
12
+ css(z).show();D.width(A.width()),D.height(A.height()),A.after(D).hide()}else D=A.css(z).show(),B=!1,d.shade===null&&(d.shade=!0);t(D,d.boxWidth,d.boxHeight);var E=D.width(),F=D.height(),G=a("<div />").width(E).height(F).addClass(j("holder")).css({position:"relative",backgroundColor:d.bgColor}).insertAfter(A).append(D);d.addClass&&G.addClass(d.addClass);var H=a("<div />"),I=a("<div />").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("<div />").width("100%").height("100%").css("zIndex",320),K=a("<div />").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("<img />").attr("src",D.attr("src")).css(z).width(E).height(F),I.append(H)),h&&K.css({overflowY:"hidden"});var L=d.boundary,M=y().width(E+L*2).height(F+L*2).css({position:"absolute",top:i(-L),left:i(-L),zIndex:290}).mousedown(w),N=d.bgColor,O=d.bgOpacity,P,Q,R,S,T,U,V=!0,W,X,Y;e=l(D);var Z=function(){function a(){var a={},b=["touchstart"
13
+ ,"touchmove","touchend"],c=document.createElement("div"),d;try{for(d=0;d<b.length;d++){var e=b[d];e="on"+e;var f=e in c;f||(c.setAttribute(e,"return;"),f=typeof c[e]=="function"),a[b[d]]=f}return a.touchstart&&a.touchend&&a.touchmove}catch(g){return!1}}function b(){return d.touchSupport===!0||d.touchSupport===!1?d.touchSupport:a()}return{createDragger:function(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(Z.cfilter(b)),!0),b.stopPropagation(),b.preventDefault(),!1)}},newSelection:function(a){return w(Z.cfilter(a))},cfilter:function(a){return a.pageX=a.originalEvent.changedTouches[0].pageX,a.pageY=a.originalEvent.changedTouches[0].pageY,a},isSupported:a,support:b()}}(),_=function(){function h(d){d=n(d),c=a=d[0],e=b=d[1]}function i(a){a=n(a),f=a[0]-c,g=a[1]-e,c=a[0],e=a[1]}function j(){return[f,g]}function k(d){var f=d[0],g=d[1];0>a+f&&(f-=f+a),0>b+g&&(g-=g+b),F<e+g&&(g+=F-(e+g)),E<c+f&&(f+=E-(c+f)),a+=f,c+=f,b+=g,e+=g}function l(a){var b=m();switch(a){case"ne":return[
14
+ b.x2,b.y];case"nw":return[b.x,b.y];case"se":return[b.x2,b.y2];case"sw":return[b.x,b.y2]}}function m(){if(!d.aspectRatio)return p();var f=d.aspectRatio,g=d.minSize[0]/T,h=d.maxSize[0]/T,i=d.maxSize[1]/U,j=c-a,k=e-b,l=Math.abs(j),m=Math.abs(k),n=l/m,r,s,t,u;return h===0&&(h=E*10),i===0&&(i=F*10),n<f?(s=e,t=m*f,r=j<0?a-t:t+a,r<0?(r=0,u=Math.abs((r-a)/f),s=k<0?b-u:u+b):r>E&&(r=E,u=Math.abs((r-a)/f),s=k<0?b-u:u+b)):(r=c,u=l/f,s=k<0?b-u:b+u,s<0?(s=0,t=Math.abs((s-b)*f),r=j<0?a-t:t+a):s>F&&(s=F,t=Math.abs(s-b)*f,r=j<0?a-t:t+a)),r>a?(r-a<g?r=a+g:r-a>h&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):r<a&&(a-r<g?r=a-g:a-r>h&&(r=a-h),s>b?s=b+(a-r)/f:s=b-(a-r)/f),r<0?(a-=r,r=0):r>E&&(a-=r-E,r=E),s<0?(b-=s,s=0):s>F&&(b-=s-F,s=F),q(o(a,b,r,s))}function n(a){return a[0]<0&&(a[0]=0),a[1]<0&&(a[1]=0),a[0]>E&&(a[0]=E),a[1]>F&&(a[1]=F),[Math.round(a[0]),Math.round(a[1])]}function o(a,b,c,d){var e=a,f=c,g=b,h=d;return c<a&&(e=c,f=a),d<b&&(g=d,h=b),[e,g,f,h]}function p(){var d=c-a,f=e-b,g;return P&&Math.abs(d)>P&&(c=d>0?a+P:a-P),Q&&Math.abs
15
+ (f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)<S/U&&(e=f>0?b+S/U:b-S/U),R/T&&Math.abs(d)<R/T&&(c=d>0?a+R/T:a-R/T),a<0&&(c-=a,a-=a),b<0&&(e-=b,b-=b),c<0&&(a-=c,c-=c),e<0&&(b-=e,e-=e),c>E&&(g=c-E,a-=g,c-=g),e>F&&(g=e-F,b-=g,e-=g),a>E&&(g=a-F,e-=g,b-=g),b>F&&(g=b-F,e-=g,b-=g),q(o(a,b,c,e))}function q(a){return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]}}var a=0,b=0,c=0,e=0,f,g;return{flipCoords:o,setPressed:h,setCurrent:i,getOffset:j,moveOffset:k,getCorner:l,getFixed:m}}(),ba=function(){function f(a,b){e.left.css({height:i(b)}),e.right.css({height:i(b)})}function g(){return h(_.getFixed())}function h(a){e.top.css({left:i(a.x),width:i(a.w),height:i(a.y)}),e.bottom.css({top:i(a.y2),left:i(a.x),width:i(a.w),height:i(F-a.y2)}),e.right.css({left:i(a.x2),width:i(E-a.x2)}),e.left.css({width:i(a.x)})}function j(){return a("<div />").css({position:"absolute",backgroundColor:d.shadeColor||d.bgColor}).appendTo(c)}function k(){b||(b=!0,c.insertBefore(D),g(),bb.setBgOpacity(1,0,1),H.hide(),l(d.shadeColor||d.bgColor,1),bb.
16
+ isAwake()?n(d.bgOpacity,1):n(1,1))}function l(a,b){bq(p(),a,b)}function m(){b&&(c.remove(),H.show(),b=!1,bb.isAwake()?bb.setBgOpacity(d.bgOpacity,1,1):(bb.setBgOpacity(1,1,1),bb.disableHandles()),bq(G,0,1))}function n(a,e){b&&(d.bgFade&&!e?c.animate({opacity:1-a},{queue:!1,duration:d.fadeTime}):c.css({opacity:1-a}))}function o(){d.shade?k():m(),bb.isAwake()&&n(d.bgOpacity)}function p(){return c.children()}var b=!1,c=a("<div />").css({position:"absolute",zIndex:240,opacity:0}),e={top:j(),left:j().height(F),right:j().height(F),bottom:j()};return{update:g,updateRaw:h,getShades:p,setBgColor:l,enable:k,disable:m,resize:f,refresh:o,opacity:n}}(),bb=function(){function k(b){var c=a("<div />").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("<div />").mousedown(s(b)).css({cursor:b+"-resize",position:"absolute",zIndex:c}).addClass("ord-"+b);return Z.support&&d.bind("touchstart.jcrop",Z.createDragger(b)),J.append(d),d}function m(a){var b=d.handleSize,e=l(a,c++
17
+ ).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b<a.length;b++)g[a[b]]=n(a[b])}function p(a){var b,c;for(c=0;c<a.length;c++){switch(a[c]){case"n":b="hline";break;case"s":b="hline bottom";break;case"e":b="vline right";break;case"w":b="vline"}e[a[c]]=k(b)}}function q(a){var b;for(b=0;b<a.length;b++)f[a[b]]=m(a[b])}function r(a,b){d.shade||H.css({top:i(-b),left:i(-a)}),K.css({top:i(b),left:i(a)})}function t(a,b){K.width(Math.round(a)).height(Math.round(b))}function v(){var a=_.getFixed();_.setPressed([a.x,a.y]),_.setCurrent([a.x2,a.y2]),w()}function w(a){if(b)return x(a)}function x(a){var c=_.getFixed();t(c.w,c.h),r(c.x,c.y),d.shade&&ba.updateRaw(c),b||A(),a?d.onSelect.call(bs,u(c)):d.onChange.call(bs,u(c))}function z(a,c,e){if(!b&&!c)return;d.bgFade&&!e?D.animate({opacity:a},{queue:!1,duration:d.fadeTime}):D.css("opacity",a)}function A(){K.show(),d.shade?ba.opacity(O):z(O,!0),b=!0}function B
18
+ (){F(),K.hide(),d.shade?ba.opacity(1):z(1),b=!1,d.onRelease.call(bs)}function C(){h&&J.show()}function E(){h=!0;if(d.allowResize)return J.show(),!0}function F(){h=!1,J.hide()}function G(a){a?(X=!0,F()):(X=!1,E())}function L(){G(!1),v()}var b,c=370,e={},f={},g={},h=!1;d.dragEdges&&a.isArray(d.createDragbars)&&o(d.createDragbars),a.isArray(d.createHandles)&&q(d.createHandles),d.drawBorders&&a.isArray(d.createBorders)&&p(d.createBorders),a(document).bind("touchstart.jcrop-ios",function(b){a(b.currentTarget).hasClass("jcrop-tracker")&&b.stopPropagation()});var M=y().mousedown(s("move")).css({cursor:"move",position:"absolute",zIndex:360});return Z.support&&M.bind("touchstart.jcrop",Z.createDragger("move")),I.append(M),F(),{updateVisible:w,update:x,release:B,refresh:v,isAwake:function(){return b},setCursor:function(a){M.css("cursor",a)},enableHandles:E,enableOnly:function(){h=!0},showHandles:C,disableHandles:F,animMode:G,setBgOpacity:z,done:L}}(),bc=function(){function f(b){M.css({zIndex:450}),b?a(document).bind("touchmove.jcrop"
19
+ ,k).bind("touchend.jcrop",l):e&&a(document).bind("mousemove.jcrop",h).bind("mouseup.jcrop",i)}function g(){M.css({zIndex:290}),a(document).unbind(".jcrop")}function h(a){return b(m(a)),!1}function i(a){return a.preventDefault(),a.stopPropagation(),W&&(W=!1,c(m(a)),bb.isAwake()&&d.onSelect.call(bs,u(_.getFixed())),g(),b=function(){},c=function(){}),!1}function j(a,d,e){return W=!0,b=a,c=d,f(e),!1}function k(a){return b(m(Z.cfilter(a))),!1}function l(a){return i(Z.cfilter(a))}function n(a){M.css("cursor",a)}var b=function(){},c=function(){},e=d.trackDocument;return e||M.mousemove(h).mouseup(i).mouseout(i),D.before(M),{activateHandlers:j,setCursor:n}}(),bd=function(){function e(){d.keySupport&&(b.show(),b.focus())}function f(a){b.hide()}function g(a,b,c){d.allowMove&&(_.moveOffset([b,c]),bb.updateVisible(!0)),a.preventDefault(),a.stopPropagation()}function i(a){if(a.ctrlKey||a.metaKey)return!0;Y=a.shiftKey?!0:!1;var b=Y?10:1;switch(a.keyCode){case 37:g(a,-b,0);break;case 39:g(a,b,0);break;case 38:g(a,0,-b);break;
20
+ case 40:g(a,0,b);break;case 27:d.allowSelect&&bb.release();break;case 9:return!0}return!1}var b=a('<input type="radio" />').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("<div />").css({position:"absolute",overflow:"hidden"}).append(b);return d.keySupport&&(b.keydown(i).blur(f),h||!d.fixedSupport?(b.css({position:"absolute",left:"-20px"}),c.append(b).insertBefore(D)):b.insertBefore(D)),{watchKeys:e}}();Z.support&&M.bind("touchstart.jcrop",Z.newSelection),J.hide(),br(!0);var bs={setImage:bp,animateTo:bf,setSelect:bg,setOptions:bk,tellSelect:bi,tellScaled:bj,setClass:be,disable:bl,enable:bm,cancel:bn,release:bb.release,destroy:bo,focus:bd.watchKeys,getBounds:function(){return[E*T,F*U]},getWidgetSize:function(){return[E,F]},getScaleFactor:function(){return[T,U]},getOptions:function(){return d},ui:{holder:G,selection:K}};return g&&G.bind("selectstart",function(){return!1}),A.data("Jcrop",bs),bs},a.fn.Jcrop=function(b,c){var d;return this.each(function(){if(a(this).data("Jcrop")){if(
21
+ b==="api")return a(this).data("Jcrop");a(this).data("Jcrop").setOptions(b)}else this.tagName=="IMG"?a.Jcrop.Loader(this,function(){a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d)}):(a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d))}),this},a.Jcrop.Loader=function(b,c,d){function g(){f.complete?(e.unbind(".jcloader"),a.isFunction(c)&&c.call(f)):window.setTimeout(g,50)}var e=a(b),f=e[0];e.bind("load.jcloader",g).bind("error.jcloader",function(b){e.unbind(".jcloader"),a.isFunction(d)&&d.call(f)}),f.complete&&a.isFunction(c)&&(e.unbind(".jcloader"),c.call(f))},a.Jcrop.defaults={allowSelect:!0,allowMove:!0,allowResize:!0,trackDocument:!0,baseClass:"jcrop",addClass:null,bgColor:"black",bgOpacity:.6,bgFade:!1,borderOpacity:.4,handleOpacity:.5,handleSize:null,aspectRatio:0,keySupport:!0,createHandles:["n","s","e","w","nw","ne","se","sw"],createDragbars:["n","s","e","w"],createBorders:["n","s","e","w"],drawBorders:!0,dragEdges
22
+ :!0,fixedSupport:!0,touchSupport:null,shade:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onDblClick:function(){},onRelease:function(){}}})(jQuery);
js/vers-0-7-0/cpt-crop.js DELETED
@@ -1,182 +0,0 @@
1
- jQuery(document).ready(function($) {
2
- var pluginpath = '../wp-content/plugins/crop-thumbnails';
3
- var adminAjaxPath = '../wp-admin/admin-ajax.php';
4
-
5
- //setup for ajax connections
6
- $.ajaxSetup({type:'POST', url:adminAjaxPath, cache:false, timeout: (30 * 1000)});
7
-
8
- //cropping object: holds jcrop-object and image to use the crop on
9
- var cropping = {api:-1, img : $('.selectionArea img')};
10
-
11
- /*needed cause the js-logic is currently not handle the hidden objects in dependence with "select all of the same ratio"*/
12
- $('.thumbnail-list li.hidden').remove();
13
-
14
- cropping.img.fadeTo(0, 0.3);
15
-
16
- //handle click on an entry
17
- $('.thumbnail-list li').click(function() {
18
- selectAllWithSameRatio($(this));
19
- activateArea(cropping);
20
- });
21
-
22
-
23
- //handle checkbox for selecting all with same ratio
24
- $('#cpt-same-ratio').change(function() {
25
- var active = $('.thumbnail-list li.active');
26
- if($(this).attr('checked')==='checked') {
27
- if(active.length>0) {
28
- selectAllWithSameRatio($(active[0]));
29
- activateArea(cropping);
30
- }
31
- } else {
32
- if(active.length>1) {
33
- $('.thumbnail-list li').removeClass('active');
34
- deactivateArea(cropping);
35
- }
36
- }
37
- });
38
-
39
-
40
- $('#cpt-deselect').click(function() {
41
- $('.thumbnail-list li.active').removeClass('active');
42
- deactivateArea(cropping);
43
- });
44
-
45
-
46
- $('#cpt-generate').click(function() {
47
- var active = $('.thumbnail-list li.active');
48
- if(active.length===0) {
49
- alert(cpt_lang['selectOne']);
50
- return;
51
- }
52
- var selection = cropping.api.tellSelect();
53
- if(active.length>0 && selection.w>0 && selection.h>0) {
54
- doProcessing(active,cropping);
55
- }
56
- });
57
-
58
- /********************************/
59
- function doProcessing(active,cropping) {
60
- /*console.log('doProcessing');*/
61
-
62
- var active_array = new Array();
63
- active.find('img').each(function() {
64
- active_array.push($(this).data('values'));
65
- });
66
-
67
- $('.mainWindow').hide();
68
- $('.waitingWindow').show();
69
-
70
- /*console.log('selection',cropping.api.tellSelect());*/
71
-
72
- $.ajax({
73
- data:{
74
- action: 'cptSaveThumbnail',
75
- '_ajax_nonce': cpt_ajax_nonce,
76
- cookie: encodeURIComponent(document.cookie),
77
- selection: JSON.stringify(cropping.api.tellSelect()),
78
- raw_values: JSON.stringify(cropping.img.data('values')),
79
- active_values: JSON.stringify(active_array)
80
- },
81
- complete : function() {
82
- $('.mainWindow').show();
83
- $('.waitingWindow').hide();
84
- },
85
- success : function( response ) {
86
- var result = JSON.parse(response);
87
- /*console.log(result);*/
88
- if(typeof result.success == "number") {
89
-
90
- if(result.changed_image_format) {
91
- window.location.reload();
92
- } else {
93
- doCacheBreaker(result.success);
94
- }
95
- } else {
96
- //saving fail
97
- alert(result.error);
98
- }
99
- }
100
- });
101
- }
102
-
103
- function doCacheBreaker(number) {
104
- $('.thumbnail-list li img').each(function() {
105
- var imgurl = $(this).attr('src');
106
- var last = imgurl.lastIndexOf('?');
107
- if(last<0) {
108
- imgurl+='?'+number;
109
- } else {
110
- imgurl = imgurl.substring(0, last) + '?'+number;
111
- }
112
- $(this).attr('src',imgurl);
113
- });
114
- }
115
-
116
- function selectAllWithSameRatio(elem) {
117
- $('.thumbnail-list li').removeClass('active');
118
- if($('#cpt-same-ratio').attr('checked')==='checked') {
119
- var ratio = elem.attr('rel');
120
- var elements = $('.thumbnail-list li[rel="'+ratio+'"]');
121
- elements.addClass('active');
122
- } else {
123
- elem.addClass('active');
124
- }
125
- }
126
-
127
-
128
- function deactivateArea(c) {
129
- if(c.api!=-1) {
130
- c.api.destroy();
131
- }
132
- }
133
-
134
- function activateArea(c,li) {
135
- deactivateArea(c);
136
- var allActiveThumbs = $('.thumbnail-list li.active img');
137
- var largestWidth = 0;
138
- var largestHeight = 0;
139
- var ratio = 0;
140
- allActiveThumbs.each(function() {
141
- if(ratio === 0) {
142
- ratio = $(this).data('values').ratio;//initial
143
- }
144
- if(ratio != $(this).data('values').ratio) {
145
- alert(cpt_lang['bug']);
146
- }
147
-
148
- //we only need to check in one dimension, cause per definition all images have to use the same ratio
149
- if($(this).data('values').width > largestWidth) {
150
- largestWidth = $(this).data('values').width;
151
- largestHeight = $(this).data('values').height;
152
- }
153
- });
154
-
155
-
156
- var scale = c.img.width() / largestWidth;
157
- var preSelect = [ 0, 0, Math.round(scale*c.img.width()), Math.round(scale*c.img.height()) ];
158
- var minSize = [ largestWidth, largestHeight ];
159
-
160
-
161
-
162
- var options = {}
163
- options.boxWidth = c.img.width();
164
- options.boxHeight = c.img.height();
165
- options.trueSize = [cropping.img.data('values').width,c.img.data('values').height];
166
- options.aspectRatio = ratio;
167
- options.setSelect = preSelect;
168
- if(largestWidth>cropping.img.data('values').width || largestHeight>cropping.img.data('values').height) {
169
- alert(cpt_lang['warningOriginalToSmall']);
170
- if(ratio>=0) {
171
- options.setSelect = [ 0, 0, cropping.img.data('values').width, Math.round(scale*c.img.height()) ];
172
- } else {
173
- options.setSelect = [ 0, 0, Math.round(scale*c.img.width()) , cropping.img.data('values').height];
174
- }
175
- } else {
176
- options.minSize = minSize;
177
- }
178
- //console.log('options',options);
179
-
180
- c.api = $.Jcrop(c.img, options);
181
- }
182
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -48,6 +48,10 @@ Currently not.
48
  * allow new crop sizes beside the ones added with the add_image_size() function (for using less disk space)
49
  * reset standard image-crop
50
  * let the user generate all image-sizes at once by define a "central point of interest"
 
 
 
 
51
 
52
  == Screenshots ==
53
 
@@ -58,6 +62,17 @@ Currently not.
58
  5. Choose what image-sizes should be hidden (for what post-types), for better usability.
59
 
60
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
61
  = 0.7.2 =
62
  * bug fix: change the way the link in the featured Image-Box is set
63
  * languages: some adjustments
48
  * allow new crop sizes beside the ones added with the add_image_size() function (for using less disk space)
49
  * reset standard image-crop
50
  * let the user generate all image-sizes at once by define a "central point of interest"
51
+ * maybe use the new WP_Image_Editor class
52
+ * add a option-button for dont use the minSize-Boundary of jcrop
53
+ * put editor-options into a collapsible menu
54
+
55
 
56
  == Screenshots ==
57
 
62
  5. Choose what image-sizes should be hidden (for what post-types), for better usability.
63
 
64
  == Changelog ==
65
+ = 0.8.0 =
66
+ * change Constant from CPT_LANG to CROP_THUMBS_LANG
67
+ * change Constant from CPT_VERSION to CROP_THUMBS_VERSION
68
+ * bug fix: wrong calculated scale in the cpt-crop.js (selection will again always fill the maximum space)
69
+ * change behavior: on landscape-ratio-images the selection will be initial in the middle of the image (portrait-ratio-images stay the same - i asume that portrait-ratio images are mostly portraits)
70
+ * add current jcrop (version v0.9.12) directly into the plugin to get rid of the subversion of cpt-crop.js for an prior version of jcrop in wordpress 3.4
71
+ * add settings-option to display debug (js and/or data)
72
+ * handle image-sizes with zero width or height
73
+ * fix notices: not set variables
74
+ * fix warnings: if an image-size is zero
75
+
76
  = 0.7.2 =
77
  * bug fix: change the way the link in the featured Image-Box is set
78
  * languages: some adjustments