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

Version Description

  • Added ACF5 compatibility.
  • Please report any compatibility issues. As this has been an urgent feature request I have not had as much time for testing as I would have liked.
Download this release

Release Info

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

Code changes from version 1.0 to 1.1

image_crop-v4.php → acf-image-crop-v4.php RENAMED
@@ -485,7 +485,7 @@ class acf_field_image_crop extends acf_field_image
485
 
486
 
487
  // register acf scripts
488
- wp_register_script('acf-input-image_crop', $this->settings['dir'] . 'js/input.js', array('acf-input', 'imgareaselect'), $this->settings['version']);
489
 
490
  wp_register_style('acf-input-image_crop', $this->settings['dir'] . 'css/input.css', array('acf-input'), $this->settings['version']);
491
  wp_register_script( 'jcrop', includes_url( 'js/jcrop/jquery.Jcrop.min.css' ));
@@ -522,7 +522,7 @@ class acf_field_image_crop extends acf_field_image
522
  function field_group_admin_enqueue_scripts()
523
  {
524
  // Note: This function can be removed if not used
525
- wp_register_script('acf-input-image-crop-options', $this->settings['dir'] . 'js/options.js', array('jquery'), $this->settings['version']);
526
  wp_enqueue_script( 'acf-input-image-crop-options');
527
 
528
  wp_register_style('acf-input-image-crop-options', $this->settings['dir'] . 'css/options.css');
485
 
486
 
487
  // register acf scripts
488
+ wp_register_script('acf-input-image_crop', $this->settings['dir'] . 'js/input-v4.js', array('acf-input', 'imgareaselect'), $this->settings['version']);
489
 
490
  wp_register_style('acf-input-image_crop', $this->settings['dir'] . 'css/input.css', array('acf-input'), $this->settings['version']);
491
  wp_register_script( 'jcrop', includes_url( 'js/jcrop/jquery.Jcrop.min.css' ));
522
  function field_group_admin_enqueue_scripts()
523
  {
524
  // Note: This function can be removed if not used
525
+ wp_register_script('acf-input-image-crop-options', $this->settings['dir'] . 'js/options-v4.js', array('jquery'), $this->settings['version']);
526
  wp_enqueue_script( 'acf-input-image-crop-options');
527
 
528
  wp_register_style('acf-input-image-crop-options', $this->settings['dir'] . 'css/options.css');
acf-image-crop-v5.php ADDED
@@ -0,0 +1,1037 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class acf_field_image_crop extends acf_field_image {
4
+
5
+
6
+ /*
7
+ * __construct
8
+ *
9
+ * This function will setup the field type data
10
+ *
11
+ * @type function
12
+ * @date 5/03/2014
13
+ * @since 5.0.0
14
+ *
15
+ * @param n/a
16
+ * @return n/a
17
+ */
18
+
19
+ function __construct() {
20
+
21
+ /*
22
+ * name (string) Single word, no spaces. Underscores allowed
23
+ */
24
+
25
+ $this->name = 'image_crop';
26
+
27
+
28
+ /*
29
+ * label (string) Multiple words, can include spaces, visible when selecting a field type
30
+ */
31
+
32
+ $this->label = __('Image with user-crop', 'acf-image_crop');
33
+
34
+
35
+ /*
36
+ * category (string) basic | content | choice | relational | jquery | layout | CUSTOM GROUP NAME
37
+ */
38
+
39
+ $this->category = 'content';
40
+
41
+
42
+ /*
43
+ * defaults (array) Array of default settings which are merged into the field object. These are used later in settings
44
+ */
45
+
46
+ $this->defaults = array(
47
+ 'force_crop' => 'no',
48
+ 'crop_type' => 'hard',
49
+ 'preview_size' => 'medium',
50
+ 'save_format' => 'id',
51
+ 'save_in_media_library' => 'yes',
52
+ 'target_size' => 'thumbnail'
53
+ );
54
+
55
+ // add ajax action to be able to retrieve full image size via javascript
56
+ add_action( 'wp_ajax_acf_image_crop_get_image_size', array( &$this, 'crop_get_image_size' ) );
57
+ add_action( 'wp_ajax_acf_image_crop_perform_crop', array( &$this, 'perform_crop' ) );
58
+
59
+
60
+ /*
61
+ * l10n (array) Array of strings that are used in JavaScript. This allows JS strings to be translated in PHP and loaded via:
62
+ * var message = acf._e('image_crop', 'error');
63
+ */
64
+
65
+ $this->l10n = array(
66
+ 'error' => __('Error! Please enter a higher value', 'acf-image_crop'),
67
+ );
68
+
69
+
70
+ // do not delete!
71
+ acf_field::__construct();
72
+ //parent::__construct();
73
+
74
+ }
75
+
76
+
77
+ // AJAX handler for retieving full image dimensions from ID
78
+ public function crop_get_image_size()
79
+ {
80
+ $img = wp_get_attachment_image_src( $_POST['image_id'], 'full');
81
+ if($img){
82
+ echo json_encode( array(
83
+ 'url' => $img[0],
84
+ 'width' => $img[1],
85
+ 'height' => $img[2]
86
+ ) );
87
+ }
88
+ exit;
89
+ }
90
+
91
+
92
+ /*
93
+ * render_field_settings()
94
+ *
95
+ * Create extra settings for your field. These are visible when editing a field
96
+ *
97
+ * @type action
98
+ * @since 3.6
99
+ * @date 23/01/13
100
+ *
101
+ * @param $field (array) the $field being edited
102
+ * @return n/a
103
+ */
104
+
105
+ function render_field_settings( $field ) {
106
+
107
+ /*
108
+ * acf_render_field_setting
109
+ *
110
+ * This function will create a setting for your field. Simply pass the $field parameter and an array of field settings.
111
+ * The array of settings does not require a `value` or `prefix`; These settings are found from the $field array.
112
+ *
113
+ * More than one setting can be added by copy/paste the above code.
114
+ * Please note that you must also have a matching $defaults value for the field name (font_size)
115
+ */
116
+
117
+ // crop_type
118
+ acf_render_field_setting( $field, array(
119
+ 'label' => __('Crop type','acf-image_crop'),
120
+ 'instructions' => __('Select the type of crop the user should perform','acf-image_crop'),
121
+ 'type' => 'select',
122
+ 'name' => 'crop_type',
123
+ 'layout' => 'horizontal',
124
+ 'class' => 'crop-type-select',
125
+ 'choices' => array(
126
+ 'hard' => __('Hard crop', 'acf-image_crop'),
127
+ 'min' => __('Minimal dimensions', 'acf-image_crop')
128
+ )
129
+ ));
130
+
131
+ // target_size
132
+ $sizes = acf_get_image_sizes();
133
+ $sizes['custom'] = __('Custom size', 'acf-image_crop');
134
+ acf_render_field_setting( $field, array(
135
+ 'label' => __('Target size','acf-image_crop'),
136
+ 'instructions' => __('Select the target size for this field','acf-image_crop'),
137
+ 'type' => 'select',
138
+ 'name' => 'target_size',
139
+ 'class' => 'target-size-select',
140
+ 'choices' => $sizes
141
+ ));
142
+
143
+ // width - conditional: target_size == 'custom'
144
+ acf_render_field_setting( $field, array(
145
+ 'label' => __('Custom target width','acf-image_crop'),
146
+ 'instructions' => __('Leave blank for no restriction (does not work with hard crop option)','acf-image_crop'),
147
+ 'type' => 'number',
148
+ 'name' => 'width',
149
+ 'class' => 'custom-target-width custom-target-dimension'
150
+ ));
151
+
152
+ // height - conditional: target_size == 'custom'
153
+ acf_render_field_setting( $field, array(
154
+ 'label' => __('Custom target height','acf-image_crop'),
155
+ 'instructions' => __('Leave blank for no restriction (does not work with hard crop option)','acf-image_crop'),
156
+ 'type' => 'number',
157
+ 'name' => 'height',
158
+ 'class' => 'custom-target-height custom-target-dimension'
159
+ ));
160
+
161
+ // preview_size
162
+ acf_render_field_setting( $field, array(
163
+ 'label' => __('Preview size','acf-image_crop'),
164
+ 'instructions' => __('Select the preview size for this field','acf-image_crop'),
165
+ 'type' => 'select',
166
+ 'name' => 'preview_size',
167
+ 'choices' => acf_get_image_sizes()
168
+ ));
169
+
170
+ // force_crop
171
+ acf_render_field_setting( $field, array(
172
+ 'label' => __('Force crop','acf-image_crop'),
173
+ 'instructions' => __('Force the user to crop the image as soon at it is selected','acf-image_crop'),
174
+ 'type' => 'radio',
175
+ 'layout' => 'horizontal',
176
+ 'name' => 'force_crop',
177
+ 'choices' => array('yes' => 'Yes', 'no' => 'No')
178
+ ));
179
+
180
+ // save_in_media_library
181
+ acf_render_field_setting( $field, array(
182
+ 'label' => __('Save cropped image to media library','acf-image_crop'),
183
+ 'instructions' => __('If the cropped image is not saved in the media library, "Image URL" is the only available return value.','acf-image_crop'),
184
+ 'type' => 'radio',
185
+ 'layout' => 'horizontal',
186
+ 'name' => 'save_in_media_library',
187
+ 'class' => 'save-in-media-library-select',
188
+ 'choices' => array('yes' => 'Yes', 'no' => 'No')
189
+ ));
190
+
191
+
192
+ // return_format
193
+ acf_render_field_setting( $field, array(
194
+ 'label' => __('Return Value','acf-image_crop'),
195
+ 'instructions' => __('Specify the returned value on front end','acf-image_crop'),
196
+ 'type' => 'radio',
197
+ 'name' => 'save_format',
198
+ 'layout' => 'horizontal',
199
+ 'class' => 'return-value-select',
200
+ 'choices' => array(
201
+ 'url' => __("Image URL",'acf'),
202
+ 'id' => __("Image ID",'acf'),
203
+ 'object' => __("Image Object",'acf')
204
+ )
205
+ ));
206
+
207
+ // library
208
+ acf_render_field_setting( $field, array(
209
+ 'label' => __('Library','acf'),
210
+ 'instructions' => __('Limit the media library choice','acf'),
211
+ 'type' => 'radio',
212
+ 'name' => 'library',
213
+ 'layout' => 'horizontal',
214
+ 'choices' => array(
215
+ 'all' => __('All', 'acf'),
216
+ 'uploadedTo' => __('Uploaded to post', 'acf')
217
+ )
218
+ ));
219
+
220
+ }
221
+
222
+
223
+
224
+ /*
225
+ * render_field()
226
+ *
227
+ * Create the HTML interface for your field
228
+ *
229
+ * @param $field (array) the $field being rendered
230
+ *
231
+ * @type action
232
+ * @since 3.6
233
+ * @date 23/01/13
234
+ *
235
+ * @param $field (array) the $field being edited
236
+ * @return n/a
237
+ */
238
+
239
+ function render_field( $field ) {
240
+
241
+
242
+ // enqueue
243
+ acf_enqueue_uploader();
244
+
245
+ // get data from value
246
+ //$data = json_decode($field['value']);
247
+ $imageData = $this->get_image_data($field);
248
+
249
+ $url = '';
250
+ $orignialImage = null;
251
+
252
+ if($imageData->original_image){
253
+ $originalImage = wp_get_attachment_image_src($imageData->original_image, 'full');
254
+ $url = $imageData->preview_image_url;
255
+ }
256
+
257
+ $width = 0;
258
+ $height = 0;
259
+
260
+ if($field['target_size'] == 'custom'){
261
+ $width = $field['width'];
262
+ $height = $field['height'];
263
+ }
264
+ else{
265
+ global $_wp_additional_image_sizes;
266
+ $s = $field['target_size'];
267
+ if (isset($_wp_additional_image_sizes[$s])) {
268
+ $width = intval($_wp_additional_image_sizes[$s]['width']);
269
+ $height = intval($_wp_additional_image_sizes[$s]['height']);
270
+ } else {
271
+ $width = get_option($s.'_size_w');
272
+ $height = get_option($s.'_size_h');
273
+ }
274
+ }
275
+
276
+ // vars
277
+ $div_atts = array(
278
+ 'class' => 'acf-image-uploader acf-cf acf-image-crop',
279
+ 'data-crop_type' => $field['crop_type'],
280
+ 'data-target_size' => $field['target_size'],
281
+ 'data-width' => $width,
282
+ 'data-height' => $height,
283
+ 'data-force_crop' => $field['force_crop'] == 'yes' ? 'true' : 'false',
284
+ 'data-save_in_media_library' => $field['save_in_media_library'] == 'yes' ? 'true' : 'false',
285
+ 'data-save_format' => $field['save_format'],
286
+ 'data-preview_size' => $field['preview_size'],
287
+ 'data-library' => $field['library']
288
+ );
289
+ $input_atts = array(
290
+ 'type' => 'hidden',
291
+ 'name' => $field['name'],
292
+ 'value' => htmlspecialchars($field['value']),
293
+ 'data-name' => 'value-id',
294
+ 'data-original-image' => $imageData->original_image,
295
+ 'data-cropped-image' => json_encode($imageData->cropped_image),
296
+ 'class' => 'acf-image-value'
297
+ );
298
+
299
+ // has value?
300
+ if($imageData->original_image){
301
+ $url = $imageData->preview_image_url;
302
+ $div_atts['class'] .= ' has-value';
303
+ }
304
+
305
+ ?>
306
+ <div <?php acf_esc_attr_e( $div_atts ); ?>>
307
+ <div class="acf-hidden">
308
+ <input <?php acf_esc_attr_e( $input_atts ); ?>/>
309
+ </div>
310
+ <div class="view show-if-value acf-soh">
311
+ <ul class="acf-hl acf-soh-target">
312
+ <li><a class="acf-icon dark" data-name="edit-button" href="#"><i class="acf-sprite-edit"></i></a></li>
313
+ <li><a class="acf-icon dark" data-name="remove-button" href="#"><i class="acf-sprite-delete"></i></a></li>
314
+ </ul>
315
+ <img data-name="value-url" src="<?php echo $url; ?>" alt=""/>
316
+ <div class="crop-section">
317
+ <div class="crop-stage">
318
+ <div class="crop-action">
319
+ <h4>Crop the image</h4>
320
+ <?php if ($imageData->original_image ): ?>
321
+ <img class="crop-image" src="<?php echo $imageData->original_image_url ?>" data-width="<?php echo $imageData->original_image_width ?>" data-height="<?php echo $imageData->original_image_height ?>" alt="">
322
+ <?php endif ?>
323
+ </div>
324
+ <div class="crop-preview">
325
+ <h4>Preview</h4>
326
+ <div class="preview"></div>
327
+ <div class="crop-controls">
328
+ <a href="#" class="button button-large cancel-crop-button">Cancel</a> <a href="#" class="button button-large button-primary perform-crop-button">Crop!</a>
329
+ </div>
330
+ </div>
331
+ <!-- <img src="<?php echo $o['url']; ?>" alt=""/> -->
332
+ </div>
333
+ <a href="#" class="button button-large init-crop-button">Crop</a>
334
+ </div>
335
+ </div>
336
+ <div class="view hide-if-value">
337
+ <p><?php _e('No image selected','acf'); ?> <a data-name="add-button" class="acf-button" href="#"><?php _e('Add Image','acf'); ?></a></p>
338
+ </div>
339
+ </div>
340
+ <?php
341
+
342
+ }
343
+
344
+ /***
345
+ * Parses the field value into a consistent data object
346
+ ****/
347
+ function get_image_data($field){
348
+ $imageData = new stdClass();
349
+ $imageData->original_image = '';
350
+ $imageData->original_image_width = '';
351
+ $imageData->original_image_height = '';
352
+ $imageData->cropped_image = '';
353
+ $imageData->original_image_url = '';
354
+ $imageData->preview_image_url = '';
355
+ $imageData->image_url = '';
356
+
357
+ if($field['value'] == ''){
358
+ // Field has not yet been saved or is an empty image field
359
+ return $imageData;
360
+ }
361
+
362
+ $data = json_decode($field['value']);
363
+
364
+ if(! is_object($data)){
365
+ // Field was saved as a regular image field
366
+ $imageAtts = wp_get_attachment_image_src($field['value'], 'full');
367
+ $imageData->original_image = $field['value'];
368
+ $imageData->original_image_width = $imageAtts[1];
369
+ $imageData->original_image_height = $imageAtts[2];
370
+ $imageData->preview_image_url = $this->get_image_src($field['value'], $field['preview_size']);
371
+ $imageData->image_url = $this->get_image_src($field['value'], 'full');
372
+ return $imageData;
373
+ }
374
+
375
+ if( !is_numeric($data->original_image) )
376
+ {
377
+ // The field has been saved, but has no image
378
+ return $imageData;
379
+ }
380
+
381
+ // By now, we have at least a saved original image
382
+ $imageAtts = wp_get_attachment_image_src($data->original_image, 'full');
383
+ $imageData->original_image = $data->original_image;
384
+ $imageData->original_image_width = $imageAtts[1];
385
+ $imageData->original_image_height = $imageAtts[2];
386
+ $imageData->original_image_url = $this->get_image_src($data->original_image, 'full');
387
+
388
+ // Set defaults to original image
389
+ $imageData->image_url = $this->get_image_src($data->original_image, 'full');
390
+ $imageData->preview_image_url = $this->get_image_src($data->original_image, $field['preview_size']);
391
+
392
+ // Check if there is a cropped version and set appropriate attributes
393
+ if(is_numeric($data->cropped_image)){
394
+ // Cropped image was saved to media library ans has an ID
395
+ $imageData->cropped_image = $data->cropped_image;
396
+ $imageData->image_url = $this->get_image_src($data->cropped_image, 'full');
397
+ $imageData->preview_image_url = $this->get_image_src($data->cropped_image, $field['preview_size']);
398
+ }
399
+ elseif(is_object($data->cropped_image)){
400
+ // Cropped image was not saved to media library and is only stored by its URL
401
+ $imageData->cropped_image = $data->cropped_image;
402
+
403
+ // Generate appropriate URLs
404
+ $mediaDir = wp_upload_dir();
405
+ $imageData->image_url = $mediaDir['baseurl'] . '/' . $data->cropped_image->image;
406
+ $imageData->preview_image_url = $mediaDir['baseurl'] . '/' . $data->cropped_image->preview;
407
+ }
408
+ return $imageData;
409
+ }
410
+
411
+
412
+ /*
413
+ * input_admin_enqueue_scripts()
414
+ *
415
+ * This action is called in the admin_enqueue_scripts action on the edit screen where your field is created.
416
+ * Use this action to add CSS + JavaScript to assist your render_field() action.
417
+ *
418
+ * @type action (admin_enqueue_scripts)
419
+ * @since 3.6
420
+ * @date 23/01/13
421
+ *
422
+ * @param n/a
423
+ * @return n/a
424
+ */
425
+
426
+
427
+
428
+ function input_admin_enqueue_scripts() {
429
+
430
+ $dir = plugin_dir_url( __FILE__ );
431
+
432
+
433
+ // // register & include JS
434
+ // wp_register_script( 'acf-input-image_crop', "{$dir}js/input.js" );
435
+ // wp_enqueue_script('acf-input-image_crop');
436
+
437
+
438
+ // // register & include CSS
439
+ // wp_register_style( 'acf-input-image_crop', "{$dir}css/input.css" );
440
+ // wp_enqueue_style('acf-input-image_crop');
441
+
442
+ // register acf scripts
443
+ wp_register_script('acf-input-image_crop', "{$dir}js/input.js", array('acf-input', 'imgareaselect'), $this->settings['version']);
444
+
445
+ wp_register_style('acf-input-image_crop', "{$dir}css/input.css", array('acf-input'), $this->settings['version']);
446
+ //wp_register_script( 'jcrop', includes_url( 'js/jcrop/jquery.Jcrop.min.css' ));
447
+
448
+
449
+ // scripts
450
+ wp_enqueue_script(array(
451
+ 'acf-input-image_crop'
452
+ ));
453
+
454
+ //wp_localize_script( 'acf-input-image_crop', 'ajax', array('nonce' => wp_create_nonce('acf_nonce')) );
455
+
456
+ // styles
457
+ wp_enqueue_style(array(
458
+ 'acf-input-image_crop',
459
+ 'imgareaselect'
460
+ ));
461
+
462
+
463
+ }
464
+
465
+ function perform_crop(){
466
+ $targetWidth = $_POST['target_width'];
467
+ $targetHeight = $_POST['target_height'];
468
+ $saveToMediaLibrary = $_POST['save_to_media_library'] == 'yes';
469
+ $imageData = $this->generate_cropped_image($_POST['id'], $_POST['x1'], $_POST['x2'], $_POST['y1'], $_POST['y2'], $targetWidth, $targetHeight, $saveToMediaLibrary, $_POST['preview_size']);
470
+ // $previewUrl = wp_get_attachment_image_src( $id, $_POST['preview_size']);
471
+ // $fullUrl = wp_get_attachment_image_src( $id, 'full');
472
+ echo json_encode($imageData);
473
+ die();
474
+ }
475
+
476
+ function generate_cropped_image($id, $x1, $x2, $y1, $y2, $targetW, $targetH, $saveToMediaLibrary, $previewSize){//$id, $x1, $x2, $y$, $y2, $targetW, $targetH){
477
+ require_once ABSPATH . "/wp-admin/includes/file.php";
478
+ require_once ABSPATH . "/wp-admin/includes/image.php";
479
+
480
+ // Create the variable that will hold the new image data
481
+ $imageData = array();
482
+
483
+ // Fetch media library info
484
+ $mediaDir = wp_upload_dir();
485
+
486
+ // Get original image info
487
+ $originalImageData = wp_get_attachment_metadata($id);
488
+
489
+ // Get image editor from original image path to crop the image
490
+ $image = wp_get_image_editor( $mediaDir['basedir'] . '/' . $originalImageData['file'] );
491
+
492
+ // Crop the image using the provided measurements
493
+ $image->crop($x1, $y1, $x2 - $x1, $y2 - $y1, $targetW, $targetH);
494
+
495
+ // Retrieve original filename and seperate it from its file extension
496
+ $originalFileName = explode('.', basename($originalImageData['file']));
497
+
498
+ // Generate new base filename
499
+ $targetFileName = $originalFileName[0] . '_' . $targetW . 'x' . $targetH . '_acf_cropped' . '.' . $originalFileName[1];
500
+
501
+ // Generate target path new file using existing media library
502
+ $targetFilePath = $mediaDir['path'] . '/' . wp_unique_filename( $mediaDir['path'], $targetFileName);
503
+
504
+ // Get the relative path to save as the actual image url
505
+ $targetRelativePath = str_replace($mediaDir['basedir'] . '/', '', $targetFilePath);
506
+
507
+ // Save the image to the target path
508
+ if(is_wp_error($image->save($targetFilePath))){
509
+ // There was an error saving the image
510
+ //TODO handle it
511
+ }
512
+
513
+ // If file should be saved to media library, create an attachment for it at get the new attachment ID
514
+ if($saveToMediaLibrary){
515
+ // Generate attachment from created file
516
+
517
+ // Get the filetype
518
+ $wp_filetype = wp_check_filetype(basename($targetFilePath), null );
519
+ $attachment = array(
520
+ 'guid' => $targetFilePath,
521
+ 'post_mime_type' => $wp_filetype['type'],
522
+ 'post_title' => preg_replace('/\.[^.]+$/', '', basename($targetFilePath)),
523
+ 'post_content' => '',
524
+ 'post_status' => 'inherit'
525
+ );
526
+ $attachmentId = wp_insert_attachment( $attachment, $targetFilePath);
527
+ $attachmentData = wp_generate_attachment_metadata( $attachmentId, $targetFilePath );
528
+ wp_update_attachment_metadata( $attachmentId, $attachmentData );
529
+
530
+ // Add the id to the imageData-array
531
+ $imageData['value'] = $attachmentId;
532
+
533
+ // Add the image url
534
+ $imageUrlObject = wp_get_attachment_image_src( $attachmentId, 'full');
535
+ $imageData['url'] = $imageUrlObject[0];
536
+
537
+ // Add the preview url as well
538
+ $previewUrlObject = wp_get_attachment_image_src( $attachmentId, $previewSize);
539
+ $imageData['preview_url'] = $previewUrlObject[0];
540
+ }
541
+ // Else we need to return the actual path of the cropped image
542
+ else{
543
+ // Add the image url to the imageData-array
544
+ $imageData['value'] = array('image' => $targetRelativePath);
545
+ $imageData['url'] = $mediaDir['baseurl'] . '/' . $targetRelativePath;
546
+
547
+ // Get preview size dimensions
548
+ global $_wp_additional_image_sizes;
549
+ $previewWidth = 0;
550
+ $previewHeight = 0;
551
+ $crop = 0;
552
+ if (isset($_wp_additional_image_sizes[$previewSize])) {
553
+ $previewWidth = intval($_wp_additional_image_sizes[$previewSize]['width']);
554
+ $previewHeight = intval($_wp_additional_image_sizes[$previewSize]['height']);
555
+ $crop = $_wp_additional_image_sizes[$previewSize]['crop'];
556
+ } else {
557
+ $previewWidth = get_option($previewSize.'_size_w');
558
+ $previewHeight = get_option($previewSize.'_size_h');
559
+ $crop = get_option($previewSize.'_crop');
560
+ }
561
+
562
+ // Generate preview file path
563
+ $previewFilePath = $mediaDir['path'] . '/' . wp_unique_filename( $mediaDir['path'], 'preview_' . $targetFileName);
564
+ $previewRelativePath = str_replace($mediaDir['basedir'] . '/', '', $previewFilePath);
565
+
566
+ // Get image editor from cropped image
567
+ $croppedImage = wp_get_image_editor( $targetFilePath );
568
+ $croppedImage->resize($previewWidth, $previewHeight, $crop);
569
+
570
+ // Save the preview
571
+ $croppedImage->save($previewFilePath);
572
+
573
+ // Add the preview url
574
+ $imageData['preview_url'] = $mediaDir['baseurl'] . '/' . $previewRelativePath;
575
+ $imageData['value']['preview'] = $previewRelativePath;
576
+ }
577
+ return $imageData;
578
+ }
579
+
580
+ function get_image_src($id, $size = 'thumbnail'){
581
+ $atts = wp_get_attachment_image_src( $id, $size);
582
+ return $atts[0];
583
+ }
584
+
585
+ function getAbsoluteImageUrl($relativeUrl){
586
+ $mediaDir = wp_upload_dir();
587
+ return $mediaDir['baseurl'] . '/' . $relativeUrl;
588
+ }
589
+
590
+
591
+
592
+
593
+ /*
594
+ * input_admin_head()
595
+ *
596
+ * This action is called in the admin_head action on the edit screen where your field is created.
597
+ * Use this action to add CSS and JavaScript to assist your render_field() action.
598
+ *
599
+ * @type action (admin_head)
600
+ * @since 3.6
601
+ * @date 23/01/13
602
+ *
603
+ * @param n/a
604
+ * @return n/a
605
+ */
606
+
607
+ /*
608
+
609
+ function input_admin_head() {
610
+
611
+
612
+
613
+ }
614
+
615
+ */
616
+
617
+
618
+
619
+
620
+ /*
621
+ * input_form_data()
622
+ *
623
+ * This function is called once on the 'input' page between the head and footer
624
+ * There are 2 situations where ACF did not load during the 'acf/input_admin_enqueue_scripts' and
625
+ * 'acf/input_admin_head' actions because ACF did not know it was going to be used. These situations are
626
+ * seen on comments / user edit forms on the front end. This function will always be called, and includes
627
+ * $args that related to the current screen such as $args['post_id']
628
+ *
629
+ * @type function
630
+ * @date 6/03/2014
631
+ * @since 5.0.0
632
+ *
633
+ * @param $args (array)
634
+ * @return n/a
635
+ */
636
+
637
+ /*
638
+
639
+ function input_form_data( $args ) {
640
+
641
+
642
+
643
+ }
644
+
645
+ */
646
+
647
+
648
+ /*
649
+ * input_admin_footer()
650
+ *
651
+ * This action is called in the admin_footer action on the edit screen where your field is created.
652
+ * Use this action to add CSS and JavaScript to assist your render_field() action.
653
+ *
654
+ * @type action (admin_footer)
655
+ * @since 3.6
656
+ * @date 23/01/13
657
+ *
658
+ * @param n/a
659
+ * @return n/a
660
+ */
661
+
662
+ /*
663
+
664
+ function input_admin_footer() {
665
+
666
+
667
+
668
+ }
669
+
670
+ */
671
+
672
+
673
+ /*
674
+ * field_group_admin_enqueue_scripts()
675
+ *
676
+ * This action is called in the admin_enqueue_scripts action on the edit screen where your field is edited.
677
+ * Use this action to add CSS + JavaScript to assist your render_field_options() action.
678
+ *
679
+ * @type action (admin_enqueue_scripts)
680
+ * @since 3.6
681
+ * @date 23/01/13
682
+ *
683
+ * @param n/a
684
+ * @return n/a
685
+ */
686
+
687
+
688
+
689
+ function field_group_admin_enqueue_scripts() {
690
+
691
+ $dir = plugin_dir_url( __FILE__ );
692
+
693
+ wp_register_script('acf-input-image-crop-options', "{$dir}js/options.js", array('jquery'), $this->settings['version']);
694
+ wp_enqueue_script( 'acf-input-image-crop-options');
695
+
696
+ wp_register_style('acf-input-image-crop-options', "{$dir}css/options.css");
697
+ wp_enqueue_style( 'acf-input-image-crop-options');
698
+ }
699
+
700
+
701
+
702
+
703
+ /*
704
+ * field_group_admin_head()
705
+ *
706
+ * This action is called in the admin_head action on the edit screen where your field is edited.
707
+ * Use this action to add CSS and JavaScript to assist your render_field_options() action.
708
+ *
709
+ * @type action (admin_head)
710
+ * @since 3.6
711
+ * @date 23/01/13
712
+ *
713
+ * @param n/a
714
+ * @return n/a
715
+ */
716
+
717
+ /*
718
+
719
+ function field_group_admin_head() {
720
+
721
+ }
722
+
723
+ */
724
+
725
+
726
+ /*
727
+ * load_value()
728
+ *
729
+ * This filter is applied to the $value after it is loaded from the db
730
+ *
731
+ * @type filter
732
+ * @since 3.6
733
+ * @date 23/01/13
734
+ *
735
+ * @param $value (mixed) the value found in the database
736
+ * @param $post_id (mixed) the $post_id from which the value was loaded
737
+ * @param $field (array) the field array holding all the field options
738
+ * @return $value
739
+ */
740
+
741
+ /*
742
+
743
+ function load_value( $value, $post_id, $field ) {
744
+
745
+ return $value;
746
+
747
+ }
748
+
749
+ */
750
+
751
+
752
+ /*
753
+ * update_value()
754
+ *
755
+ * This filter is applied to the $value before it is saved in the db
756
+ *
757
+ * @type filter
758
+ * @since 3.6
759
+ * @date 23/01/13
760
+ *
761
+ * @param $value (mixed) the value found in the database
762
+ * @param $post_id (mixed) the $post_id from which the value was loaded
763
+ * @param $field (array) the field array holding all the field options
764
+ * @return $value
765
+ */
766
+
767
+ /*
768
+
769
+ function update_value( $value, $post_id, $field ) {
770
+
771
+ return $value;
772
+
773
+ }
774
+
775
+ */
776
+
777
+
778
+ /*
779
+ * format_value()
780
+ *
781
+ * This filter is appied to the $value after it is loaded from the db and before it is returned to the template
782
+ *
783
+ * @type filter
784
+ * @since 3.6
785
+ * @date 23/01/13
786
+ *
787
+ * @param $value (mixed) the value which was loaded from the database
788
+ * @param $post_id (mixed) the $post_id from which the value was loaded
789
+ * @param $field (array) the field array holding all the field options
790
+ *
791
+ * @return $value (mixed) the modified value
792
+ */
793
+
794
+
795
+
796
+ function format_value( $value, $post_id, $field ) {
797
+
798
+ // validate
799
+ if( !$value )
800
+ {
801
+ return false;
802
+ }
803
+ $data = json_decode($value);
804
+ if(!is_object($data)){
805
+ return $value;
806
+ }
807
+
808
+ $value = $data->cropped_image;
809
+
810
+ // format
811
+ if( $field['save_format'] == 'url' )
812
+ {
813
+ if(is_numeric($data->cropped_image)){
814
+ $value = wp_get_attachment_url( $data->cropped_image );
815
+ }
816
+ elseif(is_array($data->cropped_image)){
817
+
818
+ $value = $this->getAbsoluteImageUrl($data->cropped_image['image']);
819
+ }
820
+ elseif(is_object($data->cropped_image)){
821
+ $value = $this->getAbsoluteImageUrl($data->cropped_image->image);
822
+ }
823
+
824
+ }
825
+ elseif( $field['save_format'] == 'object' )
826
+ {
827
+ if(is_numeric($data->cropped_image )){
828
+ $attachment = get_post( $data->cropped_image );
829
+ // validate
830
+ if( !$attachment )
831
+ {
832
+ return false;
833
+ }
834
+
835
+
836
+ // create array to hold value data
837
+ $src = wp_get_attachment_image_src( $attachment->ID, 'full' );
838
+
839
+ $value = array(
840
+ 'id' => $attachment->ID,
841
+ 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
842
+ 'title' => $attachment->post_title,
843
+ 'caption' => $attachment->post_excerpt,
844
+ 'description' => $attachment->post_content,
845
+ 'mime_type' => $attachment->post_mime_type,
846
+ 'url' => $src[0],
847
+ 'width' => $src[1],
848
+ 'height' => $src[2],
849
+ 'sizes' => array(),
850
+ );
851
+
852
+
853
+ // find all image sizes
854
+ $image_sizes = get_intermediate_image_sizes();
855
+
856
+ if( $image_sizes )
857
+ {
858
+ foreach( $image_sizes as $image_size )
859
+ {
860
+ // find src
861
+ $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
862
+
863
+ // add src
864
+ $value[ 'sizes' ][ $image_size ] = $src[0];
865
+ $value[ 'sizes' ][ $image_size . '-width' ] = $src[1];
866
+ $value[ 'sizes' ][ $image_size . '-height' ] = $src[2];
867
+ }
868
+ // foreach( $image_sizes as $image_size )
869
+ }
870
+ }
871
+ elseif(is_array( $data->cropped_image)){
872
+ $value = array(
873
+ 'url' => $this->getAbsoluteImageUrl($data->cropped_image['image']),
874
+ );
875
+ }
876
+ else{
877
+
878
+ //echo 'ELSE';
879
+ }
880
+
881
+ }
882
+ return $value;
883
+
884
+ }
885
+
886
+
887
+
888
+
889
+ /*
890
+ * validate_value()
891
+ *
892
+ * This filter is used to perform validation on the value prior to saving.
893
+ * All values are validated regardless of the field's required setting. This allows you to validate and return
894
+ * messages to the user if the value is not correct
895
+ *
896
+ * @type filter
897
+ * @date 11/02/2014
898
+ * @since 5.0.0
899
+ *
900
+ * @param $valid (boolean) validation status based on the value and the field's required setting
901
+ * @param $value (mixed) the $_POST value
902
+ * @param $field (array) the field array holding all the field options
903
+ * @param $input (string) the corresponding input name for $_POST value
904
+ * @return $valid
905
+ */
906
+
907
+ /*
908
+
909
+ function validate_value( $valid, $value, $field, $input ){
910
+
911
+ // Basic usage
912
+ if( $value < $field['custom_minimum_setting'] )
913
+ {
914
+ $valid = false;
915
+ }
916
+
917
+
918
+ // Advanced usage
919
+ if( $value < $field['custom_minimum_setting'] )
920
+ {
921
+ $valid = __('The value is too little!','acf-image_crop'),
922
+ }
923
+
924
+
925
+ // return
926
+ return $valid;
927
+
928
+ }
929
+
930
+ */
931
+
932
+
933
+ /*
934
+ * delete_value()
935
+ *
936
+ * This action is fired after a value has been deleted from the db.
937
+ * Please note that saving a blank value is treated as an update, not a delete
938
+ *
939
+ * @type action
940
+ * @date 6/03/2014
941
+ * @since 5.0.0
942
+ *
943
+ * @param $post_id (mixed) the $post_id from which the value was deleted
944
+ * @param $key (string) the $meta_key which the value was deleted
945
+ * @return n/a
946
+ */
947
+
948
+ /*
949
+
950
+ function delete_value( $post_id, $key ) {
951
+
952
+
953
+
954
+ }
955
+
956
+ */
957
+
958
+
959
+ /*
960
+ * load_field()
961
+ *
962
+ * This filter is applied to the $field after it is loaded from the database
963
+ *
964
+ * @type filter
965
+ * @date 23/01/2013
966
+ * @since 3.6.0
967
+ *
968
+ * @param $field (array) the field array holding all the field options
969
+ * @return $field
970
+ */
971
+
972
+ /*
973
+
974
+ function load_field( $field ) {
975
+
976
+ return $field;
977
+
978
+ }
979
+
980
+ */
981
+
982
+
983
+ /*
984
+ * update_field()
985
+ *
986
+ * This filter is applied to the $field before it is saved to the database
987
+ *
988
+ * @type filter
989
+ * @date 23/01/2013
990
+ * @since 3.6.0
991
+ *
992
+ * @param $field (array) the field array holding all the field options
993
+ * @return $field
994
+ */
995
+
996
+ /*
997
+
998
+ function update_field( $field ) {
999
+
1000
+ return $field;
1001
+
1002
+ }
1003
+
1004
+ */
1005
+
1006
+
1007
+ /*
1008
+ * delete_field()
1009
+ *
1010
+ * This action is fired after a field is deleted from the database
1011
+ *
1012
+ * @type action
1013
+ * @date 11/02/2014
1014
+ * @since 5.0.0
1015
+ *
1016
+ * @param $field (array) the field array holding all the field options
1017
+ * @return n/a
1018
+ */
1019
+
1020
+ /*
1021
+
1022
+ function delete_field( $field ) {
1023
+
1024
+
1025
+
1026
+ }
1027
+
1028
+ */
1029
+
1030
+
1031
+ }
1032
+
1033
+
1034
+ // create field
1035
+ new acf_field_image_crop();
1036
+
1037
+ ?>
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.0
7
  Author: Anders Thorborg
8
  Author URI: http://thorb.org
9
  License: GPLv2 or later
@@ -11,66 +11,32 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
  */
12
 
13
 
14
- class acf_field_image_crop_plugin
15
- {
16
- /*
17
- * Construct
18
- *
19
- * @description:
20
- * @since: 3.6
21
- * @created: 1/04/13
22
- */
23
-
24
- function __construct()
25
- {
26
- // set text domain
27
- /*
28
- $domain = 'acf-image_crop';
29
- $mofile = trailingslashit(dirname(__File__)) . 'lang/' . $domain . '-' . get_locale() . '.mo';
30
- load_textdomain( $domain, $mofile );
31
- */
32
-
33
-
34
- // version 4+
35
- add_action('acf/register_fields', array($this, 'register_fields'));
36
-
37
-
38
- // version 3-
39
- add_action('init', array( $this, 'init' ), 5);
40
- }
41
-
42
-
43
- /*
44
- * Init
45
- *
46
- * @description:
47
- * @since: 3.6
48
- * @created: 1/04/13
49
- */
50
-
51
- function init()
52
- {
53
- if(function_exists('register_field'))
54
- {
55
- register_field('acf_field_image_crop', dirname(__File__) . '/image_crop-v3.php');
56
- }
57
- }
58
-
59
- /*
60
- * register_fields
61
- *
62
- * @description:
63
- * @since: 3.6
64
- * @created: 1/04/13
65
- */
66
-
67
- function register_fields()
68
- {
69
- include_once('image_crop-v4.php');
70
- }
71
 
72
  }
73
 
74
- new acf_field_image_crop_plugin();
75
 
76
  ?>
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
7
  Author: Anders Thorborg
8
  Author URI: http://thorb.org
9
  License: GPLv2 or later
11
  */
12
 
13
 
14
+ // 1. set text domain
15
+ // Reference: https://codex.wordpress.org/Function_Reference/load_plugin_textdomain
16
+ load_plugin_textdomain( 'acf-image_crop', false, dirname( plugin_basename(__FILE__) ) . '/lang/' );
17
+
18
+
19
+
20
+
21
+ // 2. Include field type for ACF5
22
+ // $version = 5 and can be ignored until ACF6 exists
23
+ function include_field_types_image_crop( $version ) {
24
+ include_once('acf-image-crop-v5.php');
25
+
26
+ }
27
+
28
+ add_action('acf/include_field_types', 'include_field_types_image_crop');
29
+
30
+
31
+
32
+
33
+ // 3. Include field type for ACF4
34
+ function register_fields_image_crop() {
35
+
36
+ include_once('acf-image-crop-v4.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  }
39
 
40
+ add_action('acf/register_fields', 'register_fields_image_crop');
41
 
42
  ?>
js/input-v4.js ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($){
2
+
3
+
4
+ /*
5
+ * acf/setup_fields
6
+ *
7
+ * This event is triggered when ACF adds any new elements to the DOM.
8
+ *
9
+ * @type function
10
+ * @since 1.0.0
11
+ * @date 01/01/12
12
+ *
13
+ * @param event e: an event object. This can be ignored
14
+ * @param Element postbox: An element which contains the new HTML
15
+ *
16
+ * @return N/A
17
+ */
18
+
19
+ $(document).on('acf/setup_fields', function(e, postbox){
20
+ $(postbox).find('.field_type-image_crop').each(function(){
21
+ var $field = $(this), $options = $field.find('.acf-image-uploader');
22
+ $field.find('.acf-image-value').on('change', function(){
23
+ var originalImage = $(this).val();
24
+ if($(this).val()){
25
+ $field.removeClass('invalid');
26
+ $field.find('.init-crop-button').removeAttr('disabled');
27
+ $field.find('.acf-image-value').data('original-image', originalImage);
28
+ $field.find('.acf-image-value').data('cropped-image', originalImage);
29
+ $field.find('.acf-image-value').data('cropped', false);
30
+ $.post(ajaxurl, {action: 'acf_image_crop_get_image_size', image_id: originalImage}, function(data, textStatus, xhr) {
31
+ if($field.find('img.crop-image').length == 0){
32
+ $field.find('.crop-action').append($('<img class="crop-image" src="#"/>'));
33
+ }
34
+ $field.find('img.crop-image').attr('src', data['url']);
35
+ $field.find('img.crop-image').data('width', data['width']);
36
+ $field.find('img.crop-image').data('height', data['height']);
37
+ var warnings = [];
38
+ var valid = true;
39
+ if($options.data('width') && data['width'] < $options.data('width')){
40
+ warnings.push('Width should be at least: ' + $options.data('width') + 'px (Selected image width: ' + data['width'] + 'px)');
41
+ valid = false;
42
+ }
43
+ if($options.data('height') && data['height'] < $options.data('height')){
44
+ warnings.push('Height should be at least: ' + $options.data('height') + 'px (Selected image height: ' + data['height'] + 'px)');
45
+ valid = false;
46
+ }
47
+ if(!valid){
48
+ $field.addClass('invalid');
49
+ $field.find('.init-crop-button').attr('disabled', 'disabled');
50
+ alert('Warning: The selected image is smaller than the required size:\n' + warnings.join('\n'));
51
+ }
52
+ else{
53
+ if($options.data('force-crop')){
54
+ initCrop($field);
55
+ }
56
+ }
57
+
58
+ }, 'json');
59
+ updateFieldValue($field);
60
+ }
61
+ else{
62
+ //Do nothing
63
+ }
64
+
65
+ })
66
+ $field.find('.init-crop-button').click(function(e){
67
+ e.preventDefault();
68
+ initCrop($field);
69
+ });
70
+ $field.find('.perform-crop-button').click(function(e){
71
+ e.preventDefault();
72
+ performCrop($field);
73
+ });
74
+ $field.find('.cancel-crop-button').click(function(e){
75
+ e.preventDefault();
76
+ cancelCrop($field);
77
+ });
78
+ });
79
+
80
+ });
81
+
82
+ function initCrop($field){
83
+ var $options = $field.find('.acf-image-uploader');
84
+ var options = {
85
+ handles: true,
86
+ onSelectEnd: function (img, selection) {
87
+ updateThumbnail($field, img, selection);
88
+ updateCropData($field, img, selection);
89
+ },
90
+ imageWidth:$options.find('.crop-stage img.crop-image').data('width'),
91
+ imageHeight:$options.find('.crop-stage img.crop-image').data('height'),
92
+ x1: 0,
93
+ y1: 0
94
+ };
95
+ if($options.data('crop-type') == 'hard'){
96
+ options.aspectRatio = $options.data('width') + ':' + $options.data('height');
97
+ options.minWidth = $options.data('width');
98
+ options.minHeight = $options.data('height');
99
+ options.x2 = $options.data('width');
100
+ options.y2 = $options.data('height');
101
+ }
102
+ else if($options.data('crop-type') == 'min'){
103
+ if($options.data('width')){
104
+ options.minWidth = $options.data('width');
105
+ options.x2 = $options.data('width');
106
+ }
107
+ else{
108
+ options.x2 = options.imageWidth;
109
+ }
110
+ if($options.data('height')){
111
+ options.minHeight = $options.data('height');
112
+ options.y2 = $options.data('height');
113
+ }
114
+ else{
115
+ options.y2 = options.imageHeight;
116
+ }
117
+ }
118
+ // Center crop - disabled needs more testing
119
+ // options.x1 = options.imageWidth/2 - (options.minWidth/2);
120
+ // options.y1 = options.imageHeight/2 - (options.minHeight/2)
121
+ // options.x2 = options.minWidth + options.x1;
122
+ // options.y2 = options.minHeight + options.y1;
123
+ //options.y1 = (options.imageHeight - options.minHeight) / 2;
124
+ if(!$field.hasClass('invalid')){
125
+ toggleCropView($field);
126
+ $field.find('.crop-stage img.crop-image').imgAreaSelect(options);
127
+ updateCropData($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
128
+ updateThumbnail($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
129
+ }
130
+ }
131
+
132
+ function updateCropData($field, img, selection){
133
+ var $options = $field.find('.acf-image-uploader');
134
+ $options.data('x1', selection.x1);
135
+ $options.data('x2', selection.x2);
136
+ $options.data('y1', selection.y1);
137
+ $options.data('y2', selection.y2);
138
+ }
139
+
140
+ function updateThumbnail($field, img, selection){
141
+ var $options = $field.find('.acf-image-uploader');
142
+ var div = $field.find('.crop-preview .preview');
143
+ var targetWidth = $field.find('.crop-preview .preview').width();
144
+ var factor = targetWidth / (selection.x2 - selection.x1);
145
+ //image
146
+ div.css('background-image', 'url(' + img.src + ')');
147
+ //width
148
+ div.css('width', (selection.x2 - selection.x1) * factor);
149
+ //height
150
+ div.css('height', (selection.y2 - selection.y1) * factor);
151
+ //x offset
152
+ div.css('background-position-x', 0-(selection.x1 * factor));
153
+ //y offset
154
+ div.css('background-position-y', 0-(selection.y1 * factor));
155
+ div.css('background-size', $options.find('.crop-stage img.crop-image').data('width') * factor + 'px' + ' ' + $options.find('.crop-stage img.crop-image').data('height') * factor + 'px');
156
+ }
157
+
158
+ function generateCropJSON(originalImage, croppedImage){
159
+ var obj = {
160
+ original_image: originalImage,
161
+ cropped_image: croppedImage
162
+ }
163
+ return JSON.stringify(obj);
164
+ }
165
+
166
+ function performCrop($field){
167
+ if(!$field.find('.crop-stage').hasClass('loading')){
168
+ $field.find('.crop-stage').addClass('loading');
169
+ var $options = $field.find('.acf-image-uploader');
170
+ var targetWidth = $options.data('width');
171
+ var targetHeight = $options.data('height');
172
+ var saveToMediaLibrary = $options.data('save-to-media-library');
173
+ if($options.data('crop-type') == 'min'){
174
+ targetWidth = $options.data('x2') - $options.data('x1');
175
+ targetHeight = $options.data('y2') - $options.data('y1');
176
+ }
177
+ var data = {
178
+ action: 'acf_image_crop_perform_crop',
179
+ id: $field.find('.acf-image-value').data('original-image'),
180
+ x1: $options.data('x1'),
181
+ x2: $options.data('x2'),
182
+ y1: $options.data('y1'),
183
+ y2: $options.data('y2'),
184
+ target_width: targetWidth,
185
+ target_height: targetHeight,
186
+ preview_size: $options.data('preview_size'),
187
+ save_to_media_library: saveToMediaLibrary
188
+ }
189
+ $.post(ajaxurl, data, function(data, textStatus, xhr) {
190
+ $field.find('.acf-image-image').attr('src', data.preview_url);
191
+ $field.find('.acf-image-value').data('cropped-image', data.value);
192
+ $field.find('.acf-image-value').data('cropped', true);
193
+ updateFieldValue($field);
194
+ $field.find('.crop-stage').removeClass('loading');
195
+ cancelCrop($field);
196
+ }, 'json');
197
+ }
198
+ }
199
+
200
+ function cancelCrop($field){
201
+ toggleCropView($field);
202
+ $field.find('.crop-stage img.crop-image').imgAreaSelect({remove:true});
203
+ }
204
+
205
+ function toggleCropView($field){
206
+ if($field.hasClass('cropping')){
207
+ $('#acf-image-crop-overlay').remove();
208
+ }
209
+ else{
210
+ $('body').append($('<div id="acf-image-crop-overlay"></div>'));
211
+ }
212
+ $field.toggleClass('cropping');
213
+
214
+ }
215
+
216
+ function updateFieldValue($field){
217
+ var $input = $field.find('.acf-image-value');
218
+ $input.val(generateCropJSON($input.data('original-image'), $input.data('cropped-image')));
219
+ }
220
+
221
+ function getFullImageUrl(id, callback){
222
+ $.post(ajaxurl, {images: []}, function(data, textStatus, xhr) {
223
+ }, 'json');
224
+ }
225
+
226
+ })(jQuery);
js/input.js CHANGED
@@ -1,83 +1,68 @@
1
  (function($){
2
 
3
 
4
- /*
5
- * acf/setup_fields
6
- *
7
- * This event is triggered when ACF adds any new elements to the DOM.
8
- *
9
- * @type function
10
- * @since 1.0.0
11
- * @date 01/01/12
12
- *
13
- * @param event e: an event object. This can be ignored
14
- * @param Element postbox: An element which contains the new HTML
15
- *
16
- * @return N/A
17
- */
18
-
19
- $(document).on('acf/setup_fields', function(e, postbox){
20
- $(postbox).find('.field_type-image_crop').each(function(){
21
- var $field = $(this), $options = $field.find('.acf-image-uploader');
22
- $field.find('.acf-image-value').on('change', function(){
23
- var originalImage = $(this).val();
24
- if($(this).val()){
25
- $field.removeClass('invalid');
26
- $field.find('.init-crop-button').removeAttr('disabled');
27
- $field.find('.acf-image-value').data('original-image', originalImage);
28
- $field.find('.acf-image-value').data('cropped-image', originalImage);
29
- $field.find('.acf-image-value').data('cropped', false);
30
- $.post(ajaxurl, {action: 'acf_image_crop_get_image_size', image_id: originalImage}, function(data, textStatus, xhr) {
31
- if($field.find('img.crop-image').length == 0){
32
- $field.find('.crop-action').append($('<img class="crop-image" src="#"/>'));
33
- }
34
- $field.find('img.crop-image').attr('src', data['url']);
35
- $field.find('img.crop-image').data('width', data['width']);
36
- $field.find('img.crop-image').data('height', data['height']);
37
- var warnings = [];
38
- var valid = true;
39
- if($options.data('width') && data['width'] < $options.data('width')){
40
- warnings.push('Width should be at least: ' + $options.data('width') + 'px (Selected image width: ' + data['width'] + 'px)');
41
- valid = false;
42
- }
43
- if($options.data('height') && data['height'] < $options.data('height')){
44
- warnings.push('Height should be at least: ' + $options.data('height') + 'px (Selected image height: ' + data['height'] + 'px)');
45
- valid = false;
46
- }
47
- if(!valid){
48
- $field.addClass('invalid');
49
- $field.find('.init-crop-button').attr('disabled', 'disabled');
50
- alert('Warning: The selected image is smaller than the required size:\n' + warnings.join('\n'));
51
- }
52
- else{
53
- if($options.data('force-crop')){
54
- initCrop($field);
55
- }
56
  }
 
57
 
58
- }, 'json');
59
- updateFieldValue($field);
60
- }
61
- else{
62
- //Do nothing
63
- }
64
-
65
- })
66
- $field.find('.init-crop-button').click(function(e){
67
- e.preventDefault();
68
- initCrop($field);
69
- });
70
- $field.find('.perform-crop-button').click(function(e){
71
- e.preventDefault();
72
- performCrop($field);
73
- });
74
- $field.find('.cancel-crop-button').click(function(e){
75
- e.preventDefault();
76
- cancelCrop($field);
77
- });
78
  });
79
 
80
- });
81
 
82
  function initCrop($field){
83
  var $options = $field.find('.acf-image-uploader');
@@ -92,14 +77,14 @@
92
  x1: 0,
93
  y1: 0
94
  };
95
- if($options.data('crop-type') == 'hard'){
96
  options.aspectRatio = $options.data('width') + ':' + $options.data('height');
97
  options.minWidth = $options.data('width');
98
  options.minHeight = $options.data('height');
99
  options.x2 = $options.data('width');
100
  options.y2 = $options.data('height');
101
  }
102
- else if($options.data('crop-type') == 'min'){
103
  if($options.data('width')){
104
  options.minWidth = $options.data('width');
105
  options.x2 = $options.data('width');
@@ -169,8 +154,8 @@
169
  var $options = $field.find('.acf-image-uploader');
170
  var targetWidth = $options.data('width');
171
  var targetHeight = $options.data('height');
172
- var saveToMediaLibrary = $options.data('save-to-media-library');
173
- if($options.data('crop-type') == 'min'){
174
  targetWidth = $options.data('x2') - $options.data('x1');
175
  targetHeight = $options.data('y2') - $options.data('y1');
176
  }
@@ -187,7 +172,7 @@
187
  save_to_media_library: saveToMediaLibrary
188
  }
189
  $.post(ajaxurl, data, function(data, textStatus, xhr) {
190
- $field.find('.acf-image-image').attr('src', data.preview_url);
191
  $field.find('.acf-image-value').data('cropped-image', data.value);
192
  $field.find('.acf-image-value').data('cropped', true);
193
  updateFieldValue($field);
@@ -223,4 +208,65 @@
223
  }, 'json');
224
  }
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  })(jQuery);
1
  (function($){
2
 
3
 
4
+ function initialize_field( $el ) {
5
+ var $field = $el, $options = $el.find('.acf-image-uploader');
6
+ $field.find('.acf-image-value').on('change', function(){
7
+ var originalImage = $(this).val();
8
+ if($(this).val()){
9
+ $field.removeClass('invalid');
10
+ $field.find('.init-crop-button').removeAttr('disabled');
11
+ $field.find('.acf-image-value').data('original-image', originalImage);
12
+ $field.find('.acf-image-value').data('cropped-image', originalImage);
13
+ $field.find('.acf-image-value').data('cropped', false);
14
+ $.post(ajaxurl, {action: 'acf_image_crop_get_image_size', image_id: originalImage}, function(data, textStatus, xhr) {
15
+ console.log('response', data);
16
+ if($field.find('img.crop-image').length == 0){
17
+ $field.find('.crop-action').append($('<img class="crop-image" src="#"/>'));
18
+ }
19
+ $field.find('img.crop-image').attr('src', data['url']);
20
+ console.log(data['width']);
21
+ $field.find('img.crop-image').data('width', data['width']);
22
+ $field.find('img.crop-image').data('height', data['height']);
23
+ var warnings = [];
24
+ var valid = true;
25
+ if($options.data('width') && data['width'] < $options.data('width')){
26
+ warnings.push('Width should be at least: ' + $options.data('width') + 'px (Selected image width: ' + data['width'] + 'px)');
27
+ valid = false;
28
+ }
29
+ if($options.data('height') && data['height'] < $options.data('height')){
30
+ warnings.push('Height should be at least: ' + $options.data('height') + 'px (Selected image height: ' + data['height'] + 'px)');
31
+ valid = false;
32
+ }
33
+ if(!valid){
34
+ $field.addClass('invalid');
35
+ $field.find('.init-crop-button').attr('disabled', 'disabled');
36
+ alert('Warning: The selected image is smaller than the required size:\n' + warnings.join('\n'));
37
+ }
38
+ else{
39
+ if($options.data('force-crop')){
40
+ initCrop($field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
+ }
43
 
44
+ }, 'json');
45
+ updateFieldValue($field);
46
+ }
47
+ else{
48
+ //Do nothing
49
+ }
50
+
51
+ });
52
+ $field.find('.init-crop-button').click(function(e){
53
+ e.preventDefault();
54
+ initCrop($field);
55
+ });
56
+ $field.find('.perform-crop-button').click(function(e){
57
+ e.preventDefault();
58
+ performCrop($field);
59
+ });
60
+ $field.find('.cancel-crop-button').click(function(e){
61
+ e.preventDefault();
62
+ cancelCrop($field);
 
63
  });
64
 
65
+ }
66
 
67
  function initCrop($field){
68
  var $options = $field.find('.acf-image-uploader');
77
  x1: 0,
78
  y1: 0
79
  };
80
+ if($options.data('crop_type') == 'hard'){
81
  options.aspectRatio = $options.data('width') + ':' + $options.data('height');
82
  options.minWidth = $options.data('width');
83
  options.minHeight = $options.data('height');
84
  options.x2 = $options.data('width');
85
  options.y2 = $options.data('height');
86
  }
87
+ else if($options.data('crop_type') == 'min'){
88
  if($options.data('width')){
89
  options.minWidth = $options.data('width');
90
  options.x2 = $options.data('width');
154
  var $options = $field.find('.acf-image-uploader');
155
  var targetWidth = $options.data('width');
156
  var targetHeight = $options.data('height');
157
+ var saveToMediaLibrary = $options.data('save_to_media_library');
158
+ if($options.data('crop_type') == 'min'){
159
  targetWidth = $options.data('x2') - $options.data('x1');
160
  targetHeight = $options.data('y2') - $options.data('y1');
161
  }
172
  save_to_media_library: saveToMediaLibrary
173
  }
174
  $.post(ajaxurl, data, function(data, textStatus, xhr) {
175
+ $field.find('[data-name=value-url]').attr('src', data.preview_url);
176
  $field.find('.acf-image-value').data('cropped-image', data.value);
177
  $field.find('.acf-image-value').data('cropped', true);
178
  updateFieldValue($field);
208
  }, 'json');
209
  }
210
 
211
+
212
+ if( typeof acf.add_action !== 'undefined' ) {
213
+
214
+ /*
215
+ * ready append (ACF5)
216
+ *
217
+ * These are 2 events which are fired during the page load
218
+ * ready = on page load similar to $(document).ready()
219
+ * append = on new DOM elements appended via repeater field
220
+ *
221
+ * @type event
222
+ * @date 20/07/13
223
+ *
224
+ * @param $el (jQuery selection) the jQuery element which contains the ACF fields
225
+ * @return n/a
226
+ */
227
+
228
+ acf.add_action('ready append', function( $el ){
229
+
230
+ // search $el for fields of type 'image_crop'
231
+ acf.get_fields({ type : 'image_crop'}, $el).each(function(){
232
+
233
+ initialize_field( $(this) );
234
+
235
+ });
236
+
237
+ });
238
+
239
+
240
+ } else {
241
+
242
+
243
+ /*
244
+ * acf/setup_fields (ACF4)
245
+ *
246
+ * This event is triggered when ACF adds any new elements to the DOM.
247
+ *
248
+ * @type function
249
+ * @since 1.0.0
250
+ * @date 01/01/12
251
+ *
252
+ * @param event e: an event object. This can be ignored
253
+ * @param Element postbox: An element which contains the new HTML
254
+ *
255
+ * @return n/a
256
+ */
257
+
258
+ $(document).live('acf/setup_fields', function(e, postbox){
259
+
260
+ $(postbox).find('.field[data-field_type="image_crop"]').each(function(){
261
+
262
+ initialize_field( $(this) );
263
+
264
+ });
265
+
266
+ });
267
+
268
+
269
+ }
270
+
271
+
272
  })(jQuery);
js/options-v4.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($){
2
+ $(document).on('change', '.field_type-image_crop .target-size-select', function(e) {
3
+ if($(this).val() == 'custom'){
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
+ });
js/options.js CHANGED
@@ -1,31 +1,68 @@
1
  jQuery(function($){
 
 
 
 
 
 
 
 
 
 
2
  $(document).on('change', '.field_type-image_crop .target-size-select', function(e) {
3
- if($(this).val() == 'custom'){
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
  });
1
  jQuery(function($){
2
+ acf.add_action('append', function(){
3
+ $('.field_type-image_crop .target-size-select').each(function() {
4
+ toggleCustomDimensions(this);
5
+ });
6
+ $('.field_type-image_crop .save-in-media-library-select input').each(function() {
7
+ console.log(this);
8
+ toggleSaveFormats(this);
9
+ });
10
+ });
11
+
12
  $(document).on('change', '.field_type-image_crop .target-size-select', function(e) {
13
+ toggleCustomDimensions(this);
 
 
 
 
 
 
14
  });
15
+
16
+ // $(document).on('change', '.field_type-image_crop .crop-type-select', function(e) {
17
+ // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
18
+ // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
19
+ // });
20
+
21
+ $(document).on('click', '.field_type-image_crop .save-in-media-library-select input', function(e) {
22
+ toggleSaveFormats(this);
23
+ // var saveToMedia = $(this).val() == 'yes';
24
+ // var $returnValueField = $(this).parents('.field_type-image_crop').find('.return-value-select');
25
+ // if(! saveToMedia){
26
+ // $returnValueField.find('input[value=id], input[value=object]').attr('disabled', true).parents('label').addClass('disabled');
27
+ // $returnValueField.find('input[value=url]').attr('checked', true);
28
+ // }
29
+ // else{
30
+ // $returnValueField.find('input').removeAttr('disabled').parents('label').removeClass('disabled');
31
+ // }
32
+
33
+ // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
34
+ // $(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
35
+
36
  });
37
+
38
+ function toggleSaveFormats(saveToMediaSelect){
39
+ if($(saveToMediaSelect).is(':checked')){
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');
48
+ }
49
+ }
50
+ }
51
+
52
+ function toggleCustomDimensions(targetSizeSelect){
53
+ if($(targetSizeSelect).val() == 'custom'){
54
+ $(targetSizeSelect).parents('.field_type-image_crop').find('.custom-target-dimension').parents('tr.acf-field').removeClass('hidden');
55
  }
56
  else{
57
+ $(targetSizeSelect).parents('.field_type-image_crop').find('.custom-target-dimension').parents('tr.acf-field').addClass('hidden');
58
  }
59
+ }
60
+
61
+ $('.field_type-image_crop .target-size-select').each(function() {
62
+ toggleCustomDimensions(this);
63
+ });
64
+ $('.field_type-image_crop .save-in-media-library-select input').each(function() {
65
+ toggleSaveFormats(this);
66
  });
67
+
68
  });
lang/README.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ # Translations directory
2
+
3
+ Use this directory to store .po and .mo files.
4
+
5
+ This directory can be removed if not used.
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.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -61,6 +61,10 @@ function my_register_fields()
61
 
62
  == Changelog ==
63
 
 
 
 
 
64
  = 1.0 =
65
  * Added option to save the image to media library or refer directly to the created image, not using the media library.
66
  * Added better compatibility with the native image field making it possible to migrate from the regular image field to the crop-image field without losing the images currently attached. (It doesn't work the other way around)
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
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
61
 
62
  == Changelog ==
63
 
64
+ = 1.1 =
65
+ * Added ACF5 compatibility.
66
+ * Please report any compatibility issues. As this has been an urgent feature request I have not had as much time for testing as I would have liked.
67
+
68
  = 1.0 =
69
  * Added option to save the image to media library or refer directly to the created image, not using the media library.
70
  * Added better compatibility with the native image field making it possible to migrate from the regular image field to the crop-image field without losing the images currently attached. (It doesn't work the other way around)