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 | 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 +6 -0
- acf-image-crop-v4.php +201 -8
- acf-image-crop-v5.php +243 -53
- acf-image-crop.php +9 -1
- assets/banner-772/303/227250.png +0 -0
- assets/icon-256x256.png +0 -0
- js/input-v4.js +374 -0
- js/input.js +13 -0
- js/options-v4.js +18 -13
- js/options.js +4 -2
- readme.txt +10 -1
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 |
-
|
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 |
-
|
456 |
-
|
457 |
-
|
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 |
-
$
|
828 |
-
//
|
829 |
-
|
830 |
-
|
831 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
832 |
}
|
833 |
|
|
|
|
|
834 |
|
835 |
-
//
|
836 |
-
$
|
837 |
-
|
838 |
-
$value =
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
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.
|
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]
|
21 |
-
$returnValueField.find('input[value=
|
|
|
|
|
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]
|
44 |
-
$returnValueField.find('input[value=
|
|
|
|
|
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.
|
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
|