Advanced Custom Fields: Image Crop Add-on - Version 1.2

Version Description

  • Improved: Edit image is now working for most cropped image fields.
  • Fix: Wrong GUID for generated images that could cause issues when moving a site to a new location
  • Tweak: Added "original_image"-attribute when using return type "Object", containing the original image data.
  • Tweak: Return type "Object" is now available when not saving cropped image to media library. The data except from url, width and height is fetched from the original image.
  • Feature: It is now possible to hide cropped images from the media dialog. (See the new settings section) NB.: Only works for future cropped images.
  • Feature: Retina-mode, that makes the image field require and crop double the dimensions. Results in better integration with plugins like WP Retina 2x
  • Feature: Settings-seciton under Settings -> Media. Here you can choose to hide cropped images from the media dialog as well as enable/disable global retina mode.
Download this release

Release Info

Developer andersthorborg
Plugin Icon wp plugin Advanced Custom Fields: Image Crop Add-on
Version 1.2
Comparing to
See all releases

Code changes from version 1.1.4 to 1.2

README.md CHANGED
@@ -64,7 +64,13 @@ The size, that the image will ultimately be cropped into. This list includes the
64
 
65
  On the image field will be a *Crop*-button triggering the crop dialog. If the force crop option is enabled, the crop dialog will show up as soon as the user selects an image.
66
 
 
 
 
 
67
  ###Further Details
68
  Whenever the user selects an image, the original image is stored, so whenever the user decides to re-crop the image the user will see the image first selected, and not the cropped one. Every crop made creates a seperate media item, which allows for multiple uses of the same image wihtout overwriting previous crops.
69
 
 
 
70
  The plugin has only been tested with Chrome for Mac, and still needs a lot of work. Please let me know of any issues or feature requests.
64
 
65
  On the image field will be a *Crop*-button triggering the crop dialog. If the force crop option is enabled, the crop dialog will show up as soon as the user selects an image.
66
 
67
+ **Retina/@2x mode**
68
+
69
+ Makes the image field require double the dimensions selected. This makes it easier to integrate with plugins like WP Retina 2x.
70
+
71
  ###Further Details
72
  Whenever the user selects an image, the original image is stored, so whenever the user decides to re-crop the image the user will see the image first selected, and not the cropped one. Every crop made creates a seperate media item, which allows for multiple uses of the same image wihtout overwriting previous crops.
73
 
74
+ The plugin settings can be found under Settings -> Media. Here you can enable global "Retina Mode" and choose to hide cropped images from the media dialog.
75
+
76
  The plugin has only been tested with Chrome for Mac, and still needs a lot of work. Please let me know of any issues or feature requests.
acf-image-crop-v4.php CHANGED
@@ -28,16 +28,19 @@ class acf_field_image_crop extends acf_field_image
28
  'preview_size' => 'medium',
29
  'save_format' => 'id',
30
  'save_in_media_library' => 'yes',
31
- 'target_size' => 'thumbnail'
 
32
  // add default here to merge into your field.
33
  // This makes life easy when creating the field options as you don't need to use any if( isset('') ) logic. eg:
34
  //'preview_size' => 'thumbnail'
35
  );
36
 
 
 
37
  //Call grandparent cunstructor
38
  acf_field::__construct();
39
 
40
- // settings
41
  $this->settings = array(
42
  'path' => apply_filters('acf/helpers/get_path', __FILE__),
43
  'dir' => apply_filters('acf/helpers/get_dir', __FILE__),
@@ -48,6 +51,12 @@ class acf_field_image_crop extends acf_field_image
48
  add_action( 'wp_ajax_acf_image_crop_get_image_size', array( &$this, 'crop_get_image_size' ) );
49
  add_action( 'wp_ajax_acf_image_crop_perform_crop', array( &$this, 'perform_crop' ) );
50
 
 
 
 
 
 
 
51
  }
52
 
53
  // AJAX handler for retieving full image dimensions from ID
@@ -220,6 +229,32 @@ class acf_field_image_crop extends acf_field_image
220
  ?>
221
  </td>
222
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  <tr class="field_option field_option_<?php echo $this->name; ?>">
224
  <td class="label">
225
  <label><?php _e("Return Value",'acf'); ?></label>
@@ -319,6 +354,12 @@ class acf_field_image_crop extends acf_field_image
319
  $height = get_option($s.'_size_h');
320
  }
321
  }
 
 
 
 
 
 
322
  ?>
323
  <div class="acf-image-uploader clearfix <?php echo $o['class']; ?>" data-field-id="<?php echo $field['key'] ?>" data-preview_size="<?php echo $field['preview_size']; ?>" data-library="<?php echo $field['library']; ?>" data-width="<?php echo $width ?>" data-height="<?php echo $height ?>" data-crop-type="<?php echo $field['crop_type'] ?>" <?php echo ($field['force_crop'] == 'yes' ? 'data-force-crop="true"' : '')?> data-save-to-media-library="<?php echo $field['save_in_media_library'] ?>" >
324
  <input class="acf-image-value" data-original-image="<?php echo $data->original_image ?>" data-cropped-image="<?php echo json_encode($data->cropped_image) ?>" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo htmlspecialchars($field['value']); ?>" />
@@ -452,11 +493,31 @@ class acf_field_image_crop extends acf_field_image
452
  // foreach( $image_sizes as $image_size )
453
  }
454
  }
455
- elseif(is_array( $data->cropped_image)){
456
- $value = array(
457
- 'url' => $this->getAbsoluteImageUrl($data->cropped_image['image']),
458
- );
459
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  else{
461
 
462
  //echo 'ELSE';
@@ -467,6 +528,52 @@ class acf_field_image_crop extends acf_field_image
467
 
468
  }
469
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  /*
471
  * input_admin_enqueue_scripts()
472
  *
@@ -682,7 +789,7 @@ class acf_field_image_crop extends acf_field_image
682
  // Get the filetype
683
  $wp_filetype = wp_check_filetype(basename($targetFilePath), null );
684
  $attachment = array(
685
- 'guid' => $targetFilePath,
686
  'post_mime_type' => $wp_filetype['type'],
687
  'post_title' => preg_replace('/\.[^.]+$/', '', basename($targetFilePath)),
688
  'post_content' => '',
@@ -691,6 +798,7 @@ class acf_field_image_crop extends acf_field_image
691
  $attachmentId = wp_insert_attachment( $attachment, $targetFilePath);
692
  $attachmentData = wp_generate_attachment_metadata( $attachmentId, $targetFilePath );
693
  wp_update_attachment_metadata( $attachmentId, $attachmentData );
 
694
 
695
  // Add the id to the imageData-array
696
  $imageData['value'] = $attachmentId;
@@ -752,6 +860,91 @@ class acf_field_image_crop extends acf_field_image
752
  return $mediaDir['baseurl'] . '/' . $relativeUrl;
753
  }
754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
  }
756
 
757
 
28
  'preview_size' => 'medium',
29
  'save_format' => 'id',
30
  'save_in_media_library' => 'yes',
31
+ 'target_size' => 'thumbnail',
32
+ 'retina_mode' => 'no'
33
  // add default here to merge into your field.
34
  // This makes life easy when creating the field options as you don't need to use any if( isset('') ) logic. eg:
35
  //'preview_size' => 'thumbnail'
36
  );
37
 
38
+ $this->options = get_option( 'acf_image_crop_settings' );
39
+
40
  //Call grandparent cunstructor
41
  acf_field::__construct();
42
 
43
+ // settings
44
  $this->settings = array(
45
  'path' => apply_filters('acf/helpers/get_path', __FILE__),
46
  'dir' => apply_filters('acf/helpers/get_dir', __FILE__),
51
  add_action( 'wp_ajax_acf_image_crop_get_image_size', array( &$this, 'crop_get_image_size' ) );
52
  add_action( 'wp_ajax_acf_image_crop_perform_crop', array( &$this, 'perform_crop' ) );
53
 
54
+ // add filter to media query function to hide cropped images from media library
55
+ add_filter('ajax_query_attachments_args', array($this, 'filterMediaQuery'));
56
+
57
+ // Register extra fields on the media settings page on admin_init
58
+ add_action('admin_init', array($this, 'registerSettings'));
59
+
60
  }
61
 
62
  // AJAX handler for retieving full image dimensions from ID
229
  ?>
230
  </td>
231
  </tr>
232
+ <?php
233
+ $retina_instructions = __('Require and crop double the size set for this image. Enable this if you are using plugins like WP Retina 2x.','acf-image_crop');
234
+ if($this->getOption('retina_mode')){
235
+ $retina_instructions .= '<br>' . __('NB. You currently have enabled retina mode globally for all fields through <a href="' . admin_url('options-media.php') . '#acf-image-crop-retina-mode' . '">settings</a>, which will override this setting.','acf-image_crop');
236
+ }
237
+ ?>
238
+ <tr class="field_option field_option_<?php echo $this->name; ?>">
239
+ <td class="label">
240
+ <label><?php _e('Retina/@2x mode ','acf-image_crop'); ?></label>
241
+ <p><?php echo $retina_instructions ?></p>
242
+ </td>
243
+ <td>
244
+ <?php
245
+ do_action('acf/create_field', array(
246
+ 'type' => 'radio',
247
+ 'name' => 'fields['.$key.'][retina_mode]',
248
+ 'value' => $field['retina_mode'],
249
+ 'layout' => 'horizontal',
250
+ 'choices' => array(
251
+ 'yes' => __("Yes",'acf'),
252
+ 'no' => __("No",'acf')
253
+ ),
254
+ ));
255
+ ?>
256
+ </td>
257
+ </tr>
258
  <tr class="field_option field_option_<?php echo $this->name; ?>">
259
  <td class="label">
260
  <label><?php _e("Return Value",'acf'); ?></label>
354
  $height = get_option($s.'_size_h');
355
  }
356
  }
357
+
358
+ // Retina mode
359
+ if($this->getOption('retina_mode') || $field['retina_mode'] == 'yes'){
360
+ $width = $width * 2;
361
+ $height = $height * 2;
362
+ }
363
  ?>
364
  <div class="acf-image-uploader clearfix <?php echo $o['class']; ?>" data-field-id="<?php echo $field['key'] ?>" data-preview_size="<?php echo $field['preview_size']; ?>" data-library="<?php echo $field['library']; ?>" data-width="<?php echo $width ?>" data-height="<?php echo $height ?>" data-crop-type="<?php echo $field['crop_type'] ?>" <?php echo ($field['force_crop'] == 'yes' ? 'data-force-crop="true"' : '')?> data-save-to-media-library="<?php echo $field['save_in_media_library'] ?>" >
365
  <input class="acf-image-value" data-original-image="<?php echo $data->original_image ?>" data-cropped-image="<?php echo json_encode($data->cropped_image) ?>" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo htmlspecialchars($field['value']); ?>" />
493
  // foreach( $image_sizes as $image_size )
494
  }
495
  }
496
+ elseif(is_array( $data->cropped_image) || is_object($data->cropped_image)){
497
+ // Cropped image is not saved to media directory. Get data from original image instead
498
+ $value = $this->getImageArray($data->original_image);
499
+
500
+ // Get the relative url from data
501
+ $relativeUrl = '';
502
+ if(is_array( $data->cropped_image)){
503
+ $relativeUrl = $data->cropped_image['image'];
504
+ }
505
+ else{
506
+ $relativeUrl = $data->cropped_image->image;
507
+ }
508
+
509
+ // Replace URL with cropped version
510
+ $value['url'] = $this->getAbsoluteImageUrl($relativeUrl);
511
+
512
+ // Calculate and replace sizes
513
+ $imagePath = $this->getImagePath($relativeUrl);
514
+ $dimensions = getimagesize($imagePath);
515
+ $value['width'] = $dimensions[0];
516
+ $value['height'] = $dimensions[1];
517
+
518
+ // Add original image info
519
+ $value['original_image'] = $this->getImageArray($data->original_image);
520
+ }
521
  else{
522
 
523
  //echo 'ELSE';
528
 
529
  }
530
 
531
+
532
+ function getImageArray($id){
533
+ $attachment = get_post( $id );
534
+ // validate
535
+ if( !$attachment )
536
+ {
537
+ return false;
538
+ }
539
+
540
+
541
+ // create array to hold value data
542
+ $src = wp_get_attachment_image_src( $attachment->ID, 'full' );
543
+
544
+ $imageArray = array(
545
+ 'id' => $attachment->ID,
546
+ 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
547
+ 'title' => $attachment->post_title,
548
+ 'caption' => $attachment->post_excerpt,
549
+ 'description' => $attachment->post_content,
550
+ 'mime_type' => $attachment->post_mime_type,
551
+ 'url' => $src[0],
552
+ 'width' => $src[1],
553
+ 'height' => $src[2],
554
+ 'sizes' => array(),
555
+ );
556
+
557
+
558
+ // find all image sizes
559
+ $image_sizes = get_intermediate_image_sizes();
560
+
561
+ if( $image_sizes )
562
+ {
563
+ foreach( $image_sizes as $image_size )
564
+ {
565
+ // find src
566
+ $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
567
+
568
+ // add src
569
+ $imageArray[ 'sizes' ][ $image_size ] = $src[0];
570
+ $imageArray[ 'sizes' ][ $image_size . '-width' ] = $src[1];
571
+ $imageArray[ 'sizes' ][ $image_size . '-height' ] = $src[2];
572
+ }
573
+ }
574
+ return $imageArray;
575
+ }
576
+
577
  /*
578
  * input_admin_enqueue_scripts()
579
  *
789
  // Get the filetype
790
  $wp_filetype = wp_check_filetype(basename($targetFilePath), null );
791
  $attachment = array(
792
+ 'guid' => $mediaDir['url'] . '/' . basename($targetFilePath),
793
  'post_mime_type' => $wp_filetype['type'],
794
  'post_title' => preg_replace('/\.[^.]+$/', '', basename($targetFilePath)),
795
  'post_content' => '',
798
  $attachmentId = wp_insert_attachment( $attachment, $targetFilePath);
799
  $attachmentData = wp_generate_attachment_metadata( $attachmentId, $targetFilePath );
800
  wp_update_attachment_metadata( $attachmentId, $attachmentData );
801
+ add_post_meta($attachmentId, 'acf_is_cropped', 'true', true);
802
 
803
  // Add the id to the imageData-array
804
  $imageData['value'] = $attachmentId;
860
  return $mediaDir['baseurl'] . '/' . $relativeUrl;
861
  }
862
 
863
+ function getImagePath($relativePath){
864
+ $mediaDir = wp_upload_dir();
865
+ return $mediaDir['basedir'] . '/' . $relativePath;
866
+ }
867
+
868
+ function filterMediaQuery($args){
869
+ // get options
870
+ $options = get_option( 'acf_image_crop_settings' );
871
+ $hide = $options['hide_cropped'];
872
+
873
+ // If hide option is enabled, do not select items with the acf_is_cropped meta-field
874
+ if($hide){
875
+ $args['meta_query']= array(
876
+ array(
877
+ 'key' => 'acf_is_cropped',
878
+ 'compare' => 'NOT EXISTS'
879
+ )
880
+ );
881
+ }
882
+ return $args;
883
+ }
884
+
885
+
886
+ function registerSettings(){
887
+ add_settings_section(
888
+ 'acf_image_crop_settings',
889
+ __('ACF Image Crop Settings','acf-image_crop'),
890
+ array($this, 'displayImageCropSettingsSection'),
891
+ 'media'
892
+ );
893
+
894
+ register_setting(
895
+ 'media', // settings page
896
+ 'acf_image_crop_settings' // option name
897
+ );
898
+
899
+ add_settings_field(
900
+ 'acf_image_crop_hide_cropped', // id
901
+ __('Hide cropped images from media dialog', 'acf-image_crop'), // setting title
902
+ array($this, 'displayHideFromMediaInput'), // display callback
903
+ 'media', // settings page
904
+ 'acf_image_crop_settings' // settings section
905
+ );
906
+
907
+ add_settings_field(
908
+ 'acf_image_crop_retina_mode', // id
909
+ __('Enable global retina mode (beta)', 'acf-image_crop'), // setting title
910
+ array($this, 'displayRetinaModeInput'), // display callback
911
+ 'media', // settings page
912
+ 'acf_image_crop_settings' // settings section
913
+ );
914
+ }
915
+
916
+ function displayHideFromMediaInput(){
917
+ // Get plugin options
918
+ $options = get_option( 'acf_image_crop_settings' );
919
+ $value = $options['hide_cropped'];
920
+
921
+ // echo the field
922
+ ?>
923
+ <input name='acf_image_crop_settings[hide_cropped]'
924
+ type='checkbox' <?php echo $value ? 'checked' : '' ?> value='true' />
925
+ <?php
926
+ }
927
+
928
+ function displayRetinaModeInput(){
929
+ // Get plugin options
930
+ $options = get_option( 'acf_image_crop_settings' );
931
+ $value = $options['retina_mode'];
932
+
933
+ // echo the field
934
+ ?>
935
+ <input id="acf-image-crop-retina-mode" name='acf_image_crop_settings[retina_mode]'
936
+ type='checkbox' <?php echo $value ? 'checked' : '' ?> value='true' />
937
+ <?php
938
+ }
939
+
940
+ function displayImageCropSettingsSection(){
941
+ echo '';
942
+ }
943
+
944
+ function getOption($key){
945
+ return isset($this->options[$key]) ? $this->options[$key] : null;
946
+ }
947
+
948
  }
949
 
950
 
acf-image-crop-v5.php CHANGED
@@ -50,14 +50,23 @@ class acf_field_image_crop extends acf_field_image {
50
  'save_format' => 'id',
51
  'save_in_media_library' => 'yes',
52
  'target_size' => 'thumbnail',
53
- 'library' => 'all'
 
54
  );
55
 
 
 
56
  // add ajax action to be able to retrieve full image size via javascript
57
  add_action( 'wp_ajax_acf_image_crop_get_image_size', array( &$this, 'crop_get_image_size' ) );
58
  add_action( 'wp_ajax_acf_image_crop_perform_crop', array( &$this, 'perform_crop' ) );
59
 
60
 
 
 
 
 
 
 
61
  /*
62
  * l10n (array) Array of strings that are used in JavaScript. This allows JS strings to be translated in PHP and loaded via:
63
  * var message = acf._e('image_crop', 'error');
@@ -134,7 +143,7 @@ class acf_field_image_crop extends acf_field_image {
134
  $sizes['custom'] = __('Custom size', 'acf-image_crop');
135
  acf_render_field_setting( $field, array(
136
  'label' => __('Target size','acf-image_crop'),
137
- 'instructions' => __('Select the target size for this field','acf-image_crop'),
138
  'type' => 'select',
139
  'name' => 'target_size',
140
  'class' => 'target-size-select',
@@ -189,6 +198,20 @@ class acf_field_image_crop extends acf_field_image {
189
  'choices' => array('yes' => 'Yes', 'no' => 'No')
190
  ));
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  // return_format
194
  acf_render_field_setting( $field, array(
@@ -274,6 +297,12 @@ class acf_field_image_crop extends acf_field_image {
274
  }
275
  }
276
 
 
 
 
 
 
 
277
  // vars
278
  $div_atts = array(
279
  'class' => 'acf-image-uploader acf-cf acf-image-crop',
@@ -516,7 +545,7 @@ class acf_field_image_crop extends acf_field_image {
516
  // Get the filetype
517
  $wp_filetype = wp_check_filetype(basename($targetFilePath), null );
518
  $attachment = array(
519
- 'guid' => $targetFilePath,
520
  'post_mime_type' => $wp_filetype['type'],
521
  'post_title' => preg_replace('/\.[^.]+$/', '', basename($targetFilePath)),
522
  'post_content' => '',
@@ -525,6 +554,7 @@ class acf_field_image_crop extends acf_field_image {
525
  $attachmentId = wp_insert_attachment( $attachment, $targetFilePath);
526
  $attachmentData = wp_generate_attachment_metadata( $attachmentId, $targetFilePath );
527
  wp_update_attachment_metadata( $attachmentId, $attachmentData );
 
528
 
529
  // Add the id to the imageData-array
530
  $imageData['value'] = $attachmentId;
@@ -586,6 +616,89 @@ class acf_field_image_crop extends acf_field_image {
586
  return $mediaDir['baseurl'] . '/' . $relativeUrl;
587
  }
588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
 
590
 
591
 
@@ -823,60 +936,89 @@ class acf_field_image_crop extends acf_field_image {
823
  elseif( $field['save_format'] == 'object' )
824
  {
825
  if(is_numeric($data->cropped_image )){
826
-
827
- $attachment = get_post( $data->cropped_image );
828
- // validate
829
- if( !$attachment )
830
- {
831
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832
  }
833
 
 
 
834
 
835
- // create array to hold value data
836
- $src = wp_get_attachment_image_src( $attachment->ID, 'full' );
837
-
838
- $value = array(
839
- 'id' => $attachment->ID,
840
- 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
841
- 'title' => $attachment->post_title,
842
- 'caption' => $attachment->post_excerpt,
843
- 'description' => $attachment->post_content,
844
- 'mime_type' => $attachment->post_mime_type,
845
- 'url' => $src[0],
846
- 'width' => $src[1],
847
- 'height' => $src[2],
848
- 'sizes' => array(),
849
- );
850
-
851
-
852
- // find all image sizes
853
- $image_sizes = get_intermediate_image_sizes();
854
-
855
- if( $image_sizes )
856
- {
857
- foreach( $image_sizes as $image_size )
858
- {
859
- // find src
860
- $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
861
-
862
- // add src
863
- $value[ 'sizes' ][ $image_size ] = $src[0];
864
- $value[ 'sizes' ][ $image_size . '-width' ] = $src[1];
865
- $value[ 'sizes' ][ $image_size . '-height' ] = $src[2];
866
- }
867
- // foreach( $image_sizes as $image_size )
868
- }
869
- }
870
- elseif(is_array( $data->cropped_image)){
871
- $value = array(
872
- 'url' => $this->getAbsoluteImageUrl($data->cropped_image['image'])
873
- );
874
- }
875
- elseif(is_object($data->cropped_image)){
876
- $value = array(
877
- 'url' => $this->getAbsoluteImageUrl($data->cropped_image->image)
878
- );
879
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
880
  else{
881
  //echo 'ELSE';
882
  }
@@ -886,6 +1028,54 @@ class acf_field_image_crop extends acf_field_image {
886
 
887
  }
888
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
889
 
890
 
891
 
50
  'save_format' => 'id',
51
  'save_in_media_library' => 'yes',
52
  'target_size' => 'thumbnail',
53
+ 'library' => 'all',
54
+ 'retina_mode' => 'no'
55
  );
56
 
57
+ $this->options = get_option( 'acf_image_crop_settings' );
58
+
59
  // add ajax action to be able to retrieve full image size via javascript
60
  add_action( 'wp_ajax_acf_image_crop_get_image_size', array( &$this, 'crop_get_image_size' ) );
61
  add_action( 'wp_ajax_acf_image_crop_perform_crop', array( &$this, 'perform_crop' ) );
62
 
63
 
64
+ // add filter to media query function to hide cropped images from media library
65
+ add_filter('ajax_query_attachments_args', array($this, 'filterMediaQuery'));
66
+
67
+ // Register extra fields on the media settings page on admin_init
68
+ add_action('admin_init', array($this, 'registerSettings'));
69
+
70
  /*
71
  * l10n (array) Array of strings that are used in JavaScript. This allows JS strings to be translated in PHP and loaded via:
72
  * var message = acf._e('image_crop', 'error');
143
  $sizes['custom'] = __('Custom size', 'acf-image_crop');
144
  acf_render_field_setting( $field, array(
145
  'label' => __('Target size','acf-image_crop'),
146
+ 'instructions' => __('Select the target size for this field' . ($this->getOption('retina_mode') ? '<br><br><em><b>Retina mode is enabled - user will be required to select an image twice this size</b></em>' : ''),'acf-image_crop'),
147
  'type' => 'select',
148
  'name' => 'target_size',
149
  'class' => 'target-size-select',
198
  'choices' => array('yes' => 'Yes', 'no' => 'No')
199
  ));
200
 
201
+ // retina mode
202
+ $retina_instructions = __('Require and crop double the size set for this image. Enable this if you are using plugins like WP Retina 2x.','acf-image_crop');
203
+ if($this->getOption('retina_mode')){
204
+ $retina_instructions .= '<br>' . __('NB. You currently have enabled retina mode globally for all fields through <a href="' . admin_url('options-media.php') . '#acf-image-crop-retina-mode' . '">settings</a>, which will override this setting.','acf-image_crop');
205
+ }
206
+ acf_render_field_setting( $field, array(
207
+ 'label' => __('Retina/@2x mode ','acf-image_crop'),
208
+ 'instructions' => $retina_instructions,
209
+ 'type' => 'radio',
210
+ 'layout' => 'horizontal',
211
+ 'name' => 'retina_mode',
212
+ 'choices' => array('yes' => 'Yes', 'no' => 'No')
213
+ ));
214
+
215
 
216
  // return_format
217
  acf_render_field_setting( $field, array(
297
  }
298
  }
299
 
300
+ // Retina mode
301
+ if($this->getOption('retina_mode') || $field['retina_mode'] == 'yes'){
302
+ $width = $width * 2;
303
+ $height = $height * 2;
304
+ }
305
+
306
  // vars
307
  $div_atts = array(
308
  'class' => 'acf-image-uploader acf-cf acf-image-crop',
545
  // Get the filetype
546
  $wp_filetype = wp_check_filetype(basename($targetFilePath), null );
547
  $attachment = array(
548
+ 'guid' => $mediaDir['url'] . '/' . basename($targetFilePath),
549
  'post_mime_type' => $wp_filetype['type'],
550
  'post_title' => preg_replace('/\.[^.]+$/', '', basename($targetFilePath)),
551
  'post_content' => '',
554
  $attachmentId = wp_insert_attachment( $attachment, $targetFilePath);
555
  $attachmentData = wp_generate_attachment_metadata( $attachmentId, $targetFilePath );
556
  wp_update_attachment_metadata( $attachmentId, $attachmentData );
557
+ add_post_meta($attachmentId, 'acf_is_cropped', 'true', true);
558
 
559
  // Add the id to the imageData-array
560
  $imageData['value'] = $attachmentId;
616
  return $mediaDir['baseurl'] . '/' . $relativeUrl;
617
  }
618
 
619
+ function getImagePath($relativePath){
620
+ $mediaDir = wp_upload_dir();
621
+ return $mediaDir['basedir'] . '/' . $relativePath;
622
+ }
623
+
624
+ function filterMediaQuery($args){
625
+ // get options
626
+ $options = get_option( 'acf_image_crop_settings' );
627
+ $hide = $options['hide_cropped'];
628
+
629
+ // If hide option is enabled, do not select items with the acf_is_cropped meta-field
630
+ if($hide){
631
+ $args['meta_query']= array(
632
+ array(
633
+ 'key' => 'acf_is_cropped',
634
+ 'compare' => 'NOT EXISTS'
635
+ )
636
+ );
637
+ }
638
+ return $args;
639
+ }
640
+
641
+
642
+ function registerSettings(){
643
+ add_settings_section(
644
+ 'acf_image_crop_settings',
645
+ __('ACF Image Crop Settings','acf-image_crop'),
646
+ array($this, 'displayImageCropSettingsSection'),
647
+ 'media'
648
+ );
649
+
650
+ register_setting(
651
+ 'media', // settings page
652
+ 'acf_image_crop_settings' // option name
653
+ );
654
+
655
+ add_settings_field(
656
+ 'acf_image_crop_hide_cropped', // id
657
+ __('Hide cropped images from media dialog', 'acf-image_crop'), // setting title
658
+ array($this, 'displayHideFromMediaInput'), // display callback
659
+ 'media', // settings page
660
+ 'acf_image_crop_settings' // settings section
661
+ );
662
+
663
+ add_settings_field(
664
+ 'acf_image_crop_retina_mode', // id
665
+ __('Enable global retina mode (beta)', 'acf-image_crop'), // setting title
666
+ array($this, 'displayRetinaModeInput'), // display callback
667
+ 'media', // settings page
668
+ 'acf_image_crop_settings' // settings section
669
+ );
670
+ }
671
+
672
+ function displayHideFromMediaInput(){
673
+ // Get plugin options
674
+ $options = get_option( 'acf_image_crop_settings' );
675
+ $value = $options['hide_cropped'];
676
+
677
+ // echo the field
678
+ ?>
679
+ <input name='acf_image_crop_settings[hide_cropped]'
680
+ type='checkbox' <?php echo $value ? 'checked' : '' ?> value='true' />
681
+ <?php
682
+ }
683
+
684
+ function displayRetinaModeInput(){
685
+ // Get plugin options
686
+ $options = get_option( 'acf_image_crop_settings' );
687
+ $value = $options['retina_mode'];
688
+
689
+ // echo the field
690
+ ?>
691
+ <input id="acf-image-crop-retina-mode" name='acf_image_crop_settings[retina_mode]'
692
+ type='checkbox' <?php echo $value ? 'checked' : '' ?> value='true' />
693
+ <?php
694
+ }
695
+
696
+ function displayImageCropSettingsSection(){
697
+ echo '';
698
+ }
699
+
700
+
701
+
702
 
703
 
704
 
936
  elseif( $field['save_format'] == 'object' )
937
  {
938
  if(is_numeric($data->cropped_image )){
939
+ $value = $this->getImageArray($data->cropped_image);
940
+ $value['original_image'] = $this->getImageArray($data->original_image);
941
+ // $attachment = get_post( $data->cropped_image );
942
+ // // validate
943
+ // if( !$attachment )
944
+ // {
945
+ // return false;
946
+ // }
947
+
948
+
949
+ // // create array to hold value data
950
+ // $src = wp_get_attachment_image_src( $attachment->ID, 'full' );
951
+
952
+ // $value = array(
953
+ // 'id' => $attachment->ID,
954
+ // 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
955
+ // 'title' => $attachment->post_title,
956
+ // 'caption' => $attachment->post_excerpt,
957
+ // 'description' => $attachment->post_content,
958
+ // 'mime_type' => $attachment->post_mime_type,
959
+ // 'url' => $src[0],
960
+ // 'width' => $src[1],
961
+ // 'height' => $src[2],
962
+ // 'sizes' => array(),
963
+ // );
964
+
965
+
966
+ // // find all image sizes
967
+ // $image_sizes = get_intermediate_image_sizes();
968
+
969
+ // if( $image_sizes )
970
+ // {
971
+ // foreach( $image_sizes as $image_size )
972
+ // {
973
+ // // find src
974
+ // $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
975
+
976
+ // // add src
977
+ // $value[ 'sizes' ][ $image_size ] = $src[0];
978
+ // $value[ 'sizes' ][ $image_size . '-width' ] = $src[1];
979
+ // $value[ 'sizes' ][ $image_size . '-height' ] = $src[2];
980
+ // }
981
+ // // foreach( $image_sizes as $image_size )
982
+ // }
983
+ }
984
+ elseif(is_array( $data->cropped_image) || is_object($data->cropped_image)){
985
+ // Cropped image is not saved to media directory. Get data from original image instead
986
+ $value = $this->getImageArray($data->original_image);
987
+
988
+ // Get the relative url from data
989
+ $relativeUrl = '';
990
+ if(is_array( $data->cropped_image)){
991
+ $relativeUrl = $data->cropped_image['image'];
992
+ }
993
+ else{
994
+ $relativeUrl = $data->cropped_image->image;
995
  }
996
 
997
+ // Replace URL with cropped version
998
+ $value['url'] = $this->getAbsoluteImageUrl($relativeUrl);
999
 
1000
+ // Calculate and replace sizes
1001
+ $imagePath = $this->getImagePath($relativeUrl);
1002
+ $dimensions = getimagesize($imagePath);
1003
+ $value['width'] = $dimensions[0];
1004
+ $value['height'] = $dimensions[1];
1005
+
1006
+ // Add original image info
1007
+ $value['original_image'] = $this->getImageArray($data->original_image);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1008
  }
1009
+ // elseif(is_object($data->cropped_image)){
1010
+ // $value = $this->getImageArray($data->original_image);
1011
+ // $value['url'] = $this->getAbsoluteImageUrl($data->cropped_image->image);
1012
+
1013
+ // // Calculate sizes
1014
+ // $imagePath = $this->getImagePath($data->cropped_image->image);
1015
+ // $dimensions = getimagesize($imagePath);
1016
+ // $value['width'] = $dimensions[0];
1017
+ // $value['height'] = $dimensions[1];
1018
+
1019
+ // // Add original image info
1020
+ // $value['original_image'] = $this->getImageArray($data->original_image);
1021
+ // }
1022
  else{
1023
  //echo 'ELSE';
1024
  }
1028
 
1029
  }
1030
 
1031
+ function getOption($key){
1032
+ return isset($this->options[$key]) ? $this->options[$key] : null;
1033
+ }
1034
+
1035
+ function getImageArray($id){
1036
+ $attachment = get_post( $id );
1037
+ // validate
1038
+ if( !$attachment )
1039
+ {
1040
+ return false;
1041
+ }
1042
+
1043
+
1044
+ // create array to hold value data
1045
+ $src = wp_get_attachment_image_src( $attachment->ID, 'full' );
1046
+
1047
+ $imageArray = array(
1048
+ 'id' => $attachment->ID,
1049
+ 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
1050
+ 'title' => $attachment->post_title,
1051
+ 'caption' => $attachment->post_excerpt,
1052
+ 'description' => $attachment->post_content,
1053
+ 'mime_type' => $attachment->post_mime_type,
1054
+ 'url' => $src[0],
1055
+ 'width' => $src[1],
1056
+ 'height' => $src[2],
1057
+ 'sizes' => array(),
1058
+ );
1059
+
1060
+
1061
+ // find all image sizes
1062
+ $image_sizes = get_intermediate_image_sizes();
1063
+
1064
+ if( $image_sizes )
1065
+ {
1066
+ foreach( $image_sizes as $image_size )
1067
+ {
1068
+ // find src
1069
+ $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
1070
+
1071
+ // add src
1072
+ $imageArray[ 'sizes' ][ $image_size ] = $src[0];
1073
+ $imageArray[ 'sizes' ][ $image_size . '-width' ] = $src[1];
1074
+ $imageArray[ 'sizes' ][ $image_size . '-height' ] = $src[2];
1075
+ }
1076
+ }
1077
+ return $imageArray;
1078
+ }
1079
 
1080
 
1081
 
acf-image-crop.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Advanced Custom Fields: Image Crop Add-on
4
  Plugin URI: https://github.com/andersthorborg/ACF-Image-Crop
5
  Description: An image field making it possible/required for the user to crop the selected image to the specified image size or dimensions
6
- Version: 1.1.4
7
  Author: Anders Thorborg
8
  Author URI: http://thorb.org
9
  License: GPLv2 or later
@@ -39,4 +39,12 @@ function register_fields_image_crop() {
39
 
40
  add_action('acf/register_fields', 'register_fields_image_crop');
41
 
 
 
 
 
 
 
 
 
42
  ?>
3
  Plugin Name: Advanced Custom Fields: Image Crop Add-on
4
  Plugin URI: https://github.com/andersthorborg/ACF-Image-Crop
5
  Description: An image field making it possible/required for the user to crop the selected image to the specified image size or dimensions
6
+ Version: 1.2
7
  Author: Anders Thorborg
8
  Author URI: http://thorb.org
9
  License: GPLv2 or later
39
 
40
  add_action('acf/register_fields', 'register_fields_image_crop');
41
 
42
+
43
+ add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'acf_image_crop_action_links' );
44
+
45
+ function acf_image_crop_action_links( $links ) {
46
+ $links[] = '<a href="'. get_admin_url(null, 'options-media.php') .'">Settings</a>';
47
+ return $links;
48
+ }
49
+
50
  ?>
assets/banner-772/303/227250.png ADDED
Binary file
assets/icon-256x256.png ADDED
Binary file
js/input-v4.js CHANGED
@@ -75,6 +75,24 @@
75
  e.preventDefault();
76
  cancelCrop($field);
77
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  });
79
 
80
  });
@@ -223,4 +241,360 @@
223
  }, 'json');
224
  }
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  })(jQuery);
75
  e.preventDefault();
76
  cancelCrop($field);
77
  });
78
+ $field.on('click', '.acf-image-uploader .acf-button-edit', function( e ){
79
+ e.preventDefault();
80
+ e.stopPropagation();
81
+ var id = $field.find('.acf-image-value').data('cropped-image');
82
+ if(!$.isNumeric(id)){
83
+ id = $field.find('.acf-image-value').data('original-image');;
84
+ }
85
+ acf.fields.image_crop.set({ $el : $(this).closest('.acf-image-uploader') }).edit(id);
86
+ });
87
+ // $field.find('[data-name=edit-button]').click(function(e){
88
+ // e.preventDefault();
89
+ // e.stopPropagation();
90
+ // var id = $field.find('.acf-image-value').data('cropped-image');
91
+ // if(!$.isNumeric(id)){
92
+ // id = $field.find('.acf-image-value').data('original-image');;
93
+ // }
94
+ // //acf.fields.image_crop.edits(id);
95
+ //});
96
  });
97
 
98
  });
241
  }, 'json');
242
  }
243
 
244
+
245
+ // reference
246
+ var _media = acf.media;
247
+
248
+
249
+ acf.fields.image_crop = {
250
+
251
+ $el : null,
252
+ $input : null,
253
+
254
+ o : {},
255
+
256
+ set : function( o ){
257
+
258
+ // merge in new option
259
+ $.extend( this, o );
260
+
261
+
262
+ // find input
263
+ this.$input = this.$el.find('input[type="hidden"]');
264
+
265
+
266
+ // get options
267
+ this.o = acf.helpers.get_atts( this.$el );
268
+
269
+
270
+ // multiple?
271
+ this.o.multiple = this.$el.closest('.repeater').exists() ? true : false;
272
+
273
+
274
+ // wp library query
275
+ this.o.query = {
276
+ type : 'image'
277
+ };
278
+
279
+
280
+ // library
281
+ if( this.o.library == 'uploadedTo' )
282
+ {
283
+ this.o.query.uploadedTo = acf.o.post_id;
284
+ }
285
+
286
+
287
+ // return this for chaining
288
+ return this;
289
+
290
+ },
291
+ init : function(){
292
+
293
+ // is clone field?
294
+ if( acf.helpers.is_clone_field(this.$input) )
295
+ {
296
+ return;
297
+ }
298
+
299
+ },
300
+ add : function( image ){
301
+
302
+ // this function must reference a global div variable due to the pre WP 3.5 uploader
303
+ // vars
304
+ var div = _media.div;
305
+
306
+
307
+ // set atts
308
+ div.find('.acf-image-image').attr( 'src', image.url );
309
+ div.find('.acf-image-value').val( image.id ).trigger('change');
310
+
311
+
312
+ // set div class
313
+ div.addClass('active');
314
+
315
+
316
+ // validation
317
+ div.closest('.field').removeClass('error');
318
+
319
+ },
320
+ edit : function(id){
321
+
322
+
323
+
324
+ // set global var
325
+ _media.div = this.$el;
326
+
327
+
328
+ // clear the frame
329
+ _media.clear_frame();
330
+
331
+
332
+ // create the media frame
333
+ _media.frame = wp.media({
334
+ title : acf.l10n.image.edit,
335
+ multiple : false,
336
+ button : { text : acf.l10n.image.update }
337
+ });
338
+
339
+
340
+ // log events
341
+ /*
342
+ acf.media.frame.on('all', function(e){
343
+
344
+ console.log( e );
345
+
346
+ });
347
+ */
348
+
349
+ // open
350
+ _media.frame.on('open',function() {
351
+
352
+ // set to browse
353
+ if( _media.frame.content._mode != 'browse' )
354
+ {
355
+ _media.frame.content.mode('browse');
356
+ }
357
+
358
+ // add class
359
+ _media.frame.$el.closest('.media-modal').addClass('acf-media-modal acf-expanded');
360
+
361
+
362
+ // set selection
363
+ var selection = _media.frame.state().get('selection'),
364
+ attachment = wp.media.attachment( id );
365
+
366
+
367
+ // to fetch or not to fetch
368
+ if( $.isEmptyObject(attachment.changed) )
369
+ {
370
+ attachment.fetch();
371
+ }
372
+
373
+ selection.add( attachment );
374
+ });
375
+
376
+
377
+ // close
378
+ _media.frame.on('close',function(){
379
+
380
+ // remove class
381
+ _media.frame.$el.closest('.media-modal').removeClass('acf-media-modal');
382
+
383
+ });
384
+
385
+
386
+ // Finally, open the modal
387
+ acf.media.frame.open();
388
+
389
+ },
390
+ remove : function()
391
+ {
392
+
393
+ // set atts
394
+ this.$el.find('.acf-image-image').attr( 'src', '' );
395
+ this.$el.find('.acf-image-value').val( '' ).trigger('change');
396
+
397
+
398
+ // remove class
399
+ this.$el.removeClass('active');
400
+
401
+ },
402
+ popup : function()
403
+ {
404
+ // reference
405
+ var t = this;
406
+
407
+ // set global var
408
+ _media.div = this.$el;
409
+
410
+
411
+ // clear the frame
412
+ _media.clear_frame();
413
+
414
+
415
+ // Create the media frame
416
+ _media.frame = wp.media({
417
+ states : [
418
+ new wp.media.controller.Library({
419
+ library : wp.media.query( t.o.query ),
420
+ multiple : t.o.multiple,
421
+ title : acf.l10n.image.select,
422
+ priority : 20,
423
+ filterable : 'all'
424
+ })
425
+ ]
426
+ });
427
+
428
+
429
+ /*acf.media.frame.on('all', function(e){
430
+
431
+ console.log( e );
432
+
433
+ });*/
434
+
435
+
436
+ // customize model / view
437
+ acf.media.frame.on('content:activate', function(){
438
+ // vars
439
+ var toolbar = null,
440
+ filters = null;
441
+
442
+
443
+ // populate above vars making sure to allow for failure
444
+ try
445
+ {
446
+ toolbar = acf.media.frame.content.get().toolbar;
447
+ filters = toolbar.get('filters');
448
+ }
449
+ catch(e)
450
+ {
451
+ // one of the objects was 'undefined'... perhaps the frame open is Upload Files
452
+ //console.log( e );
453
+ }
454
+
455
+
456
+ // validate
457
+ if( !filters )
458
+ {
459
+ return false;
460
+ }
461
+
462
+
463
+ // filter only images
464
+ $.each( filters.filters, function( k, v ){
465
+
466
+ v.props.type = 'image';
467
+
468
+ });
469
+
470
+
471
+ // no need for 'uploaded' filter
472
+ if( t.o.library == 'uploadedTo' )
473
+ {
474
+ filters.$el.find('option[value="uploaded"]').remove();
475
+ filters.$el.after('<span>' + acf.l10n.image.uploadedTo + '</span>')
476
+
477
+ $.each( filters.filters, function( k, v ){
478
+
479
+ v.props.uploadedTo = acf.o.post_id;
480
+
481
+ });
482
+ }
483
+
484
+
485
+ // remove non image options from filter list
486
+ filters.$el.find('option').each(function(){
487
+
488
+ // vars
489
+ var v = $(this).attr('value');
490
+
491
+
492
+ // don't remove the 'uploadedTo' if the library option is 'all'
493
+ if( v == 'uploaded' && t.o.library == 'all' )
494
+ {
495
+ return;
496
+ }
497
+
498
+ if( v.indexOf('image') === -1 )
499
+ {
500
+ $(this).remove();
501
+ }
502
+
503
+ });
504
+
505
+
506
+ // set default filter
507
+ filters.$el.val('image').trigger('change');
508
+
509
+ });
510
+
511
+
512
+ // When an image is selected, run a callback.
513
+ acf.media.frame.on( 'select', function() {
514
+
515
+ // get selected images
516
+ selection = _media.frame.state().get('selection');
517
+
518
+ if( selection )
519
+ {
520
+ var i = 0;
521
+
522
+ selection.each(function(attachment){
523
+
524
+ // counter
525
+ i++;
526
+
527
+
528
+ // select / add another image field?
529
+ if( i > 1 )
530
+ {
531
+ // vars
532
+ var $td = _media.div.closest('td'),
533
+ $tr = $td.closest('.row'),
534
+ $repeater = $tr.closest('.repeater'),
535
+ key = $td.attr('data-field_key'),
536
+ selector = 'td .acf-image-uploader:first';
537
+
538
+
539
+ // key only exists for repeater v1.0.1 +
540
+ if( key )
541
+ {
542
+ selector = 'td[data-field_key="' + key + '"] .acf-image-uploader';
543
+ }
544
+
545
+
546
+ // add row?
547
+ if( ! $tr.next('.row').exists() )
548
+ {
549
+ $repeater.find('.add-row-end').trigger('click');
550
+
551
+ }
552
+
553
+
554
+ // update current div
555
+ _media.div = $tr.next('.row').find( selector );
556
+
557
+ }
558
+
559
+
560
+ // vars
561
+ var image = {
562
+ id : attachment.id,
563
+ url : attachment.attributes.url
564
+ };
565
+
566
+ // is preview size available?
567
+ if( attachment.attributes.sizes && attachment.attributes.sizes[ t.o.preview_size ] )
568
+ {
569
+ image.url = attachment.attributes.sizes[ t.o.preview_size ].url;
570
+ }
571
+
572
+ // add image to field
573
+ acf.fields.image.add( image );
574
+
575
+
576
+ });
577
+ // selection.each(function(attachment){
578
+ }
579
+ // if( selection )
580
+
581
+ });
582
+ // acf.media.frame.on( 'select', function() {
583
+
584
+
585
+ // Finally, open the modal
586
+ acf.media.frame.open();
587
+
588
+
589
+ return false;
590
+ },
591
+
592
+ // temporary gallery fix
593
+ text : {
594
+ title_add : "Select Image",
595
+ title_edit : "Edit Image"
596
+ }
597
+
598
+ };
599
+
600
  })(jQuery);
js/input.js CHANGED
@@ -59,6 +59,19 @@
59
  e.preventDefault();
60
  cancelCrop($field);
61
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  }
64
 
59
  e.preventDefault();
60
  cancelCrop($field);
61
  });
62
+ $field.find('[data-name=edit-button]').click(function(e){
63
+ e.preventDefault();
64
+ e.stopPropagation();
65
+ var id = $field.find('.acf-image-value').data('cropped-image');
66
+ if(!$.isNumeric(id)){
67
+ id = $field.find('.acf-image-value').data('original-image');;
68
+ }
69
+ acf.media.edit_popup({
70
+ title : acf._e('image', 'edit'),
71
+ button : acf._e('image', 'update'),
72
+ id : id
73
+ });
74
+ });
75
 
76
  }
77
 
js/options-v4.js CHANGED
@@ -4,28 +4,33 @@ jQuery(function($){
4
  $(this).parents('.field_type-image_crop').find('.dimensions-wrap').removeClass('hidden');
5
  }
6
  else{
7
- $(this).parents('.field_type-image_crop').find('.dimensions-wrap').addClass('hidden');
8
  }
9
-
10
  });
11
- $(document).on('change', '.field_type-image_crop .crop-type-select', function(e) {
12
  $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
13
- $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
14
-
15
  });
16
- $(document).on('click', '.field_type-image_crop .save-in-media-library-select input', function(e) {
17
- var saveToMedia = $(this).val() == 'yes';
18
  var $returnValueField = $(this).parents('.field_type-image_crop').find('.return-value-select');
19
- if(! saveToMedia){
20
- $returnValueField.find('input[value=id], input[value=object]').attr('disabled', true).parents('label').addClass('disabled');
21
- $returnValueField.find('input[value=url]').attr('checked', true);
 
 
22
  }
23
  else{
24
  $returnValueField.find('input').removeAttr('disabled').parents('label').removeClass('disabled');
25
  }
26
-
27
  // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
28
- // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
29
-
 
 
 
30
  });
31
  });
4
  $(this).parents('.field_type-image_crop').find('.dimensions-wrap').removeClass('hidden');
5
  }
6
  else{
7
+ $(this).parents('.field_type-image_crop').find('.dimensions-wrap').addClass('hidden');
8
  }
9
+
10
  });
11
+ $(document).on('change', '.field_type-image_crop .crop-type-select', function(e) {
12
  $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
13
+ $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
14
+
15
  });
16
+ $(document).on('click', '.field_type-image_crop .save-in-media-library-select input', function(e) {
17
+ var saveToMedia = $(this).val() == 'yes';
18
  var $returnValueField = $(this).parents('.field_type-image_crop').find('.return-value-select');
19
+ if(! saveToMedia){
20
+ $returnValueField.find('input[value=id]').attr('disabled', true).parents('label').addClass('disabled');
21
+ if($returnValueField.find('input[value=id]').is(':checked')){
22
+ $returnValueField.find('input[value=url]').attr('checked', true);
23
+ }
24
  }
25
  else{
26
  $returnValueField.find('input').removeAttr('disabled').parents('label').removeClass('disabled');
27
  }
28
+
29
  // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
30
+ // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
31
+
32
+ });
33
+ $('.field_type-image_crop .save-in-media-library-select input:checked').each(function(){
34
+ $(this).click();
35
  });
36
  });
js/options.js CHANGED
@@ -40,8 +40,10 @@ jQuery(function($){
40
  var saveToMedia = $(saveToMediaSelect).val() == 'yes';
41
  var $returnValueField = $(saveToMediaSelect).parents('.field_type-image_crop').find('.return-value-select');
42
  if(! saveToMedia){
43
- $returnValueField.find('input[value=id], input[value=object]').attr('disabled', true).parents('label').addClass('disabled');
44
- $returnValueField.find('input[value=url]').attr('checked', true);
 
 
45
  }
46
  else{
47
  $returnValueField.find('input').removeAttr('disabled').parents('label').removeClass('disabled');
40
  var saveToMedia = $(saveToMediaSelect).val() == 'yes';
41
  var $returnValueField = $(saveToMediaSelect).parents('.field_type-image_crop').find('.return-value-select');
42
  if(! saveToMedia){
43
+ $returnValueField.find('input[value=id]').attr('disabled', true).parents('label').addClass('disabled');
44
+ if($returnValueField.find('input[value=id]').is(':checked')){
45
+ $returnValueField.find('input[value=url]').attr('checked', true);
46
+ }
47
  }
48
  else{
49
  $returnValueField.find('input').removeAttr('disabled').parents('label').removeClass('disabled');
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: andersthorborg
3
  Tags: afc, advanced custom fields, image crop, image, crop
4
  Requires at least: 3.5
5
  Tested up to: 3.9.1
6
- Stable tag: 1.1.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -61,6 +61,15 @@ function my_register_fields()
61
 
62
  == Changelog ==
63
 
 
 
 
 
 
 
 
 
 
64
  = 1.1.4 =
65
  * Fixed an issue causing a php warning when editing custom fields
66
  * Fixed a js-issue causing image-crop-field hiding all subfields when editing repeater-/flexible content-fields
3
  Tags: afc, advanced custom fields, image crop, image, crop
4
  Requires at least: 3.5
5
  Tested up to: 3.9.1
6
+ Stable tag: 1.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
61
 
62
  == Changelog ==
63
 
64
+ = 1.2 =
65
+ * Improved: Edit image is now working for most cropped image fields.
66
+ * Fix: Wrong GUID for generated images that could cause issues when moving a site to a new location
67
+ * Tweak: Added "original_image"-attribute when using return type "Object", containing the original image data.
68
+ * Tweak: Return type "Object" is now available when not saving cropped image to media library. The data except from url, width and height is fetched from the original image.
69
+ * Feature: It is now possible to hide cropped images from the media dialog. (See the new settings section) NB.: Only works for future cropped images.
70
+ * Feature: Retina-mode, that makes the image field require and crop double the dimensions. Results in better integration with plugins like WP Retina 2x
71
+ * Feature: Settings-seciton under Settings -> Media. Here you can choose to hide cropped images from the media dialog as well as enable/disable global retina mode.
72
+
73
  = 1.1.4 =
74
  * Fixed an issue causing a php warning when editing custom fields
75
  * Fixed a js-issue causing image-crop-field hiding all subfields when editing repeater-/flexible content-fields