PluginProbe
Advanced Custom Fields (ACF®) / 4.1.2
Advanced Custom Fields (ACF®) v4.1.2
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / core / fields / image.php
image.php
874 lines 17.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class acf_field_image extends acf_field
4 {
5
6 /*
7 * __construct
8 *
9 * Set name / label needed for actions / filters
10 *
11 * @since 3.6
12 * @date 23/01/13
13 */
14
15 function __construct()
16 {
17 // vars
18 $this->name = 'image';
19 $this->label = __("Image",'acf');
20 $this->category = __("Content",'acf');
21
22
23 // do not delete!
24 parent::__construct();
25
26
27 // extra
28 add_filter('get_media_item_args', array($this, 'get_media_item_args'));
29 add_action('acf_head-update_attachment-' . $this->name, array($this, 'acf_head_update_attachment'));
30 add_action('admin_head-media-upload-popup', array($this, 'popup_head'));
31
32 add_action('wp_ajax_acf/fields/image/get_images', array($this, 'ajax_get_images'), 10, 1);
33 add_action('wp_ajax_nopriv_acf/fields/image/get_images', array($this, 'ajax_get_images'), 10, 1);
34 add_action('wp_prepare_attachment_for_js', array($this, 'wp_prepare_attachment_for_js'), 10, 3);
35 }
36
37
38 /*
39 * create_field()
40 *
41 * Create the HTML interface for your field
42 *
43 * @param $field - an array holding all the field's data
44 *
45 * @type action
46 * @since 3.6
47 * @date 23/01/13
48 */
49
50 function create_field( $field )
51 {
52 // vars
53 $class = "";
54 $file_src = "";
55 $preview_size = isset($field['preview_size']) ? $field['preview_size'] : 'thumbnail';
56
57 // get image url
58 if($field['value'] != '' && is_numeric($field['value']))
59 {
60 $file_src = wp_get_attachment_image_src($field['value'], $preview_size);
61 $file_src = $file_src[0];
62
63 if($file_src)
64 {
65 $class = "active";
66 }
67 }
68
69 ?>
70 <div class="acf-image-uploader clearfix <?php echo $class; ?>" data-preview_size="<?php echo $preview_size; ?>">
71 <input class="acf-image-value" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo $field['value']; ?>" />
72 <div class="has-image">
73 <div class="hover">
74 <ul class="bl">
75 <li><a class="acf-button-delete ir" href="#"><?php _e("Remove",'acf'); ?></a></li>
76 <li><a class="acf-button-edit ir" href="#"><?php _e("Edit",'acf'); ?></a></li>
77 </ul>
78 </div>
79 <img src="<?php echo $file_src; ?>" alt=""/>
80 </div>
81 <div class="no-image">
82 <p><?php _e('No image selected','acf'); ?> <input type="button" class="button add-image" value="<?php _e('Add Image','acf'); ?>" />
83 </div>
84 </div>
85 <?php
86 }
87
88
89 /*
90 * create_options()
91 *
92 * Create extra options for your field. This is rendered when editing a field.
93 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
94 *
95 * @type action
96 * @since 3.6
97 * @date 23/01/13
98 *
99 * @param $field - an array holding all the field's data
100 */
101
102 function create_options( $field )
103 {
104 // vars
105 $defaults = array(
106 'save_format' => 'id',
107 'preview_size' => 'thumbnail',
108 );
109
110 $field = array_merge($defaults, $field);
111 $key = $field['name'];
112
113 ?>
114 <tr class="field_option field_option_<?php echo $this->name; ?>">
115 <td class="label">
116 <label><?php _e("Return Value",'acf'); ?></label>
117 </td>
118 <td>
119 <?php
120 do_action('acf/create_field', array(
121 'type' => 'radio',
122 'name' => 'fields['.$key.'][save_format]',
123 'value' => $field['save_format'],
124 'layout' => 'horizontal',
125 'choices' => array(
126 'object' => __("Image Object",'acf'),
127 'url' => __("Image URL",'acf'),
128 'id' => __("Image ID",'acf')
129 )
130 ));
131 ?>
132 </td>
133 </tr>
134 <tr class="field_option field_option_<?php echo $this->name; ?>">
135 <td class="label">
136 <label><?php _e("Preview Size",'acf'); ?></label>
137 </td>
138 <td>
139 <?php
140
141 do_action('acf/create_field', array(
142 'type' => 'radio',
143 'name' => 'fields['.$key.'][preview_size]',
144 'value' => $field['preview_size'],
145 'layout' => 'horizontal',
146 'choices' => apply_filters('acf/get_image_sizes', array())
147 ));
148
149 ?>
150 </td>
151 </tr>
152 <?php
153
154 }
155
156
157 /*
158 * format_value_for_api()
159 *
160 * This filter is appied to the $value after it is loaded from the db and before it is passed back to the api functions such as the_field
161 *
162 * @type filter
163 * @since 3.6
164 * @date 23/01/13
165 *
166 * @param $value - the value which was loaded from the database
167 * @param $post_id - the $post_id from which the value was loaded
168 * @param $field - the field array holding all the field options
169 *
170 * @return $value - the modified value
171 */
172
173 function format_value_for_api( $value, $post_id, $field )
174 {
175 // vars
176 $defaults = array(
177 'save_format' => 'url',
178 );
179
180 $field = array_merge($defaults, $field);
181
182
183 // validate
184 if( !$value )
185 {
186 return false;
187 }
188
189
190 // format
191 if( $field['save_format'] == 'url' )
192 {
193 $value = wp_get_attachment_url( $value );
194 }
195 elseif( $field['save_format'] == 'object' )
196 {
197 $attachment = get_post( $value );
198
199
200 // validate
201 if( !$attachment )
202 {
203 return false;
204 }
205
206
207 // create array to hold value data
208 $src = wp_get_attachment_image_src( $attachment->ID, 'full' );
209
210 $value = array(
211 'id' => $attachment->ID,
212 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
213 'title' => $attachment->post_title,
214 'caption' => $attachment->post_excerpt,
215 'description' => $attachment->post_content,
216 'url' => $src[0],
217 'width' => $src[1],
218 'height' => $src[2],
219 'sizes' => array(),
220 );
221
222
223 // find all image sizes
224 $image_sizes = get_intermediate_image_sizes();
225
226 if( $image_sizes )
227 {
228 foreach( $image_sizes as $image_size )
229 {
230 // find src
231 $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
232
233 // add src
234 $value[ 'sizes' ][ $image_size ] = $src[0];
235 $value[ 'sizes' ][ $image_size . '-width' ] = $src[1];
236 $value[ 'sizes' ][ $image_size . '-height' ] = $src[2];
237 }
238 // foreach( $image_sizes as $image_size )
239 }
240 // if( $image_sizes )
241
242 }
243
244 return $value;
245
246 }
247
248
249 /*
250 * get_media_item_args
251 *
252 * @description:
253 * @since: 3.6
254 * @created: 27/01/13
255 */
256
257 function get_media_item_args( $vars )
258 {
259 $vars['send'] = true;
260 return($vars);
261 }
262
263
264 /*
265 * acf_head_update_attachment
266 *
267 * @description:
268 * @since: 3.2.7
269 * @created: 4/07/12
270 */
271
272 function acf_head_update_attachment()
273 {
274 ?>
275 <script type="text/javascript">
276 (function($){
277
278 // vars
279 var div = self.parent.acf.media.div;
280
281
282 // add message
283 self.parent.acf.helpers.add_message("<?php _e("Image Updated.",'acf'); ?>", div);
284
285
286 })(jQuery);
287 </script>
288 <?php
289 }
290
291
292 /*
293 * ajax_get_images
294 *
295 * @description:
296 * @since: 3.5.7
297 * @created: 13/01/13
298 */
299
300 function ajax_get_images()
301 {
302 // vars
303 $options = array(
304 'nonce' => '',
305 'images' => array(),
306 'preview_size' => 'thumbnail'
307 );
308 $return = array();
309
310
311 // load post options
312 $options = array_merge($options, $_POST);
313
314
315 // verify nonce
316 if( ! wp_verify_nonce($options['nonce'], 'acf_nonce') )
317 {
318 die(0);
319 }
320
321
322 if( $options['images'] )
323 {
324 foreach( $options['images'] as $id )
325 {
326 $src = wp_get_attachment_image_src( $id, $options['preview_size'] );
327
328
329 $return[] = array(
330 'id' => $id,
331 'src' => $src[0],
332 );
333 }
334 }
335
336
337 // return json
338 echo json_encode( $return );
339 die;
340
341 }
342
343
344 /*
345 * popup_head
346 *
347 * @description: css + js for thickbox
348 * @since: 1.1.4
349 * @created: 7/12/12
350 */
351
352 function popup_head()
353 {
354 // options
355 $defaults = array(
356 'acf_type' => '',
357 'acf_preview_size' => 'thumbnail',
358 'tab' => 'type',
359 );
360
361 $options = array_merge($defaults, $_GET);
362
363
364 // validate
365 if( $options['acf_type'] != 'image' )
366 {
367 return;
368 }
369
370
371 // update attachment
372 if( isset($_POST["attachments"]) )
373 {
374 echo '<div class="updated"><p>' . __("Media attachment updated.") . '</p></div>';
375 }
376
377
378 ?><style type="text/css">
379 #media-upload-header #sidemenu li#tab-type_url,
380 #media-items .media-item a.toggle,
381 #media-items .media-item tr.image-size,
382 #media-items .media-item tr.align,
383 #media-items .media-item tr.url,
384 #media-items .media-item .slidetoggle {
385 display: none !important;
386 }
387
388 #media-items .media-item {
389 position: relative;
390 overflow: hidden;
391 }
392
393 #media-items .media-item .acf-checkbox {
394 float: left;
395 margin: 28px 10px 0;
396 }
397
398 #media-items .media-item .pinkynail {
399 max-width: 64px;
400 max-height: 64px;
401 display: block !important;
402 margin: 2px;
403 }
404
405 #media-items .media-item .filename.new {
406 min-height: 0;
407 padding: 20px 10px 10px 10px;
408 line-height: 15px;
409 }
410
411 #media-items .media-item .title {
412 line-height: 14px;
413 }
414
415 #media-items .media-item .acf-select {
416 float: right;
417 margin: 22px 12px 0 10px;
418 }
419
420 #media-upload .ml-submit {
421 display: none !important;
422 }
423
424 #media-upload .acf-submit {
425 margin: 1em 0;
426 padding: 1em 0;
427 position: relative;
428 overflow: hidden;
429 display: none; /* default is hidden */
430 clear: both;
431 }
432
433 #media-upload .acf-submit a {
434 float: left;
435 margin: 0 10px 0 0;
436 }
437
438 <?php if( $options['tab'] == 'gallery' ): ?>
439 #sort-buttons,
440 #gallery-form > .widefat,
441 #media-items .menu_order,
442 #gallery-settings {
443 display: none !important;
444 }
445 <?php endif; ?>
446
447 </style>
448 <script type="text/javascript">
449 (function($){
450
451 /*
452 * Select Image
453 *
454 * @description:
455 * @since: 2.0.4
456 * @created: 11/12/12
457 */
458
459 $('#media-items .media-item a.acf-select').live('click', function(){
460
461 var id = $(this).attr('href');
462
463
464 // IE7 Fix
465 if( id.indexOf("/") != -1 )
466 {
467 var split = id.split("/");
468 id = split[split.length-1];
469 }
470
471
472 var ajax_data = {
473 action : 'acf/fields/image/get_images',
474 nonce : self.parent.acf.nonce,
475 images : [ id ],
476 preview_size : "<?php echo $options['acf_preview_size']; ?>"
477 };
478
479
480 // ajax
481 $.ajax({
482 url: ajaxurl,
483 type: 'post',
484 data : ajax_data,
485 cache: false,
486 dataType: "json",
487 success: function( json ) {
488
489 // validate
490 if( !json )
491 {
492 return false;
493 }
494
495
496 // add file
497 self.parent.acf.fields.image.add( json[0] );
498
499 self.parent.tb_remove();
500
501
502 }
503 });
504
505
506 return false;
507 });
508
509
510
511 /*
512 * Select Images
513 *
514 * @description:
515 * @since: 2.0.4
516 * @created: 11/12/12
517 */
518
519 $('#acf-add-selected').live('click', function(){
520
521 // check total
522 var total = $('#media-items .media-item .acf-checkbox:checked').length;
523 if( total == 0 )
524 {
525 alert("<?php _e("No images selected",'acf'); ?>");
526 return false;
527 }
528
529
530 var ajax_data = {
531 action : 'acf/fields/image/get_images',
532 nonce : self.parent.acf.nonce,
533 images : [],
534 preview_size : "<?php echo $options['acf_preview_size']; ?>"
535 };
536
537
538 // add to id array
539 $('#media-items .media-item .acf-checkbox:checked').each(function(){
540
541 ajax_data.images.push( $(this).val() );
542
543 });
544
545
546 // ajax
547 $.ajax({
548 url: ajaxurl,
549 type: 'post',
550 data : ajax_data,
551 cache: false,
552 dataType: "json",
553 success: function( json ) {
554
555 // validate
556 if( !json )
557 {
558 return false;
559 }
560
561
562
563 var selection = json,
564 i = 0;
565
566
567 $.each( json, function( k, image ){
568
569 // counter
570 i++;
571
572
573 // vars
574 var div = self.parent.acf.media.div;
575
576
577 // add image to field
578 self.parent.acf.fields.image.add( image );
579
580
581 // select / add another file field?
582 if( i < selection.length )
583 {
584 var tr = div.closest('tr'),
585 repeater = tr.closest('.repeater');
586
587
588 if( tr.next('.row').exists() )
589 {
590 self.parent.acf.media.div = tr.next('.row').find('.acf-image-uploader');
591 }
592 else
593 {
594 // add row
595 repeater.find('.add-row-end').trigger('click');
596
597 // set div to new row file
598 self.parent.acf.media.div = repeater.find('> table > tbody > tr.row:last .acf-image-uploader');
599 }
600 }
601
602 });
603
604
605 self.parent.tb_remove();
606
607 }
608 });
609
610
611 return false;
612
613 });
614
615
616 /*
617 * Edit Attachment Toggle
618 *
619 * @description:
620 * @since: 2.0.4
621 * @created: 11/12/12
622 */
623
624 $('#media-items .media-item a.acf-toggle-edit').live('click', function(){
625
626 // vars
627 var a = $(this),
628 item = a.closest('.media-item');
629
630
631 // toggle
632 if( a.hasClass('active') )
633 {
634 a.removeClass('active');
635 item.find('.slidetoggle').attr('style', 'display: none !important');
636 }
637 else
638 {
639 a.addClass('active');
640 item.find('.slidetoggle').attr('style', 'display: table !important');
641 }
642
643
644 // return
645 return false;
646
647 });
648
649
650 /*
651 * add_buttons
652 *
653 * @description:
654 * @since: 2.0.4
655 * @created: 11/12/12
656 */
657
658 function add_buttons()
659 {
660 // vars
661 var is_sub_field = (self.parent.acf.media.div.closest('.repeater').length > 0) ? true : false;
662
663
664 // add submit after media items (on for sub fields)
665 if($('.acf-submit').length == 0 && is_sub_field)
666 {
667 $('#media-items').after('<div class="acf-submit"><a id="acf-add-selected" class="button"><?php _e("Add Selected Images",'acf'); ?></a></div>');
668 }
669
670
671 // add buttons to media items
672 $('#media-items .media-item:not(.acf-active)').each(function(){
673
674 // show the add all button
675 $('.acf-submit').show();
676
677 // needs attachment ID
678 if($(this).children('input[id*="type-of-"]').length == 0){ return false; }
679
680 // only once!
681 $(this).addClass('acf-active');
682
683 // find id
684 var id = $(this).children('input[id*="type-of-"]').attr('id').replace('type-of-', '');
685
686 // if inside repeater, add checkbox
687 if(is_sub_field)
688 {
689 $(this).prepend('<input type="checkbox" class="acf-checkbox" value="' + id + '" <?php if( $options['tab'] == "type" ){echo 'checked="checked"';} ?> />');
690 }
691
692 // Add edit button
693 $(this).find('.filename.new').append('<br /><a href="#" class="acf-toggle-edit">Edit</a>');
694
695 // Add select button
696 $(this).find('.filename.new').before('<a href="' + id + '" class="button acf-select"><?php _e("Select Image",'acf'); ?></a>');
697
698 // add save changes button
699 $(this).find('tr.submit input.button').hide().before('<input type="submit" value="<?php _e("Update Image",'acf'); ?>" class="button savebutton" />');
700
701
702 });
703 }
704 <?php
705
706 // run the acf_add_buttons ever 500ms when on the image upload tab
707 if( $options['tab'] == "type" ): ?>
708 var acf_t = setInterval(function(){
709 add_buttons();
710 }, 500);
711 <?php endif; ?>
712
713
714 // add acf input filters to allow for tab navigation
715 $(document).ready(function(){
716
717 setTimeout(function(){
718 add_buttons();
719 }, 1);
720
721
722 $('form#filter').each(function(){
723
724 $(this).append('<input type="hidden" name="acf_preview_size" value="<?php echo $options['acf_preview_size']; ?>" />');
725 $(this).append('<input type="hidden" name="acf_type" value="image" />');
726
727 });
728
729 $('form#image-form, form#library-form').each(function(){
730
731 var action = $(this).attr('action');
732 action += "&acf_type=image&acf_preview_size=<?php echo $options['acf_preview_size']; ?>";
733 $(this).attr('action', action);
734
735 });
736
737
738 <?php
739
740 // add support for media tags
741
742 if( $options['tab'] == 'mediatags' ): ?>
743 $('#media-items .mediatag-item-count a').each(function(){
744
745 var href = $(this).attr('href');
746 href += "&acf_type=image&acf_preview_size=<?php echo $options['acf_preview_size']; ?>";
747 $(this).attr('href', href);
748
749 });
750 <?php endif; ?>
751 });
752
753 })(jQuery);
754 </script><?php
755
756 }
757
758
759 /*
760 * image_size_names_choose
761 *
762 * @description:
763 * @since: 3.5.7
764 * @created: 13/01/13
765 */
766
767 function image_size_names_choose( $sizes )
768 {
769 global $_wp_additional_image_sizes;
770
771 if( $_wp_additional_image_sizes )
772 {
773 foreach( $_wp_additional_image_sizes as $k => $v )
774 {
775 $title = $k;
776 $title = str_replace('-', ' ', $title);
777 $title = str_replace('_', ' ', $title);
778 $title = ucwords( $title );
779
780 $sizes[ $k ] = $title;
781 }
782 // foreach( $image_sizes as $image_size )
783 }
784
785 return $sizes;
786 }
787
788
789 /*
790 * wp_prepare_attachment_for_js
791 *
792 * @description: This sneaky hook adds the missing sizes to each attachment in the 3.5 uploader. It would be a lot easier to add all the sizes to the 'image_size_names_choose' filter but then it will show up on the normal the_content editor
793 * @since: 3.5.7
794 * @created: 13/01/13
795 */
796
797 function wp_prepare_attachment_for_js( $response, $attachment, $meta )
798 {
799 // only for image
800 if( $response['type'] != 'image' )
801 {
802 return $response;
803 }
804
805
806 // make sure sizes exist. Perhaps they dont?
807 if( !isset($meta['sizes']) )
808 {
809 return $response;
810 }
811
812
813 $attachment_url = $response['url'];
814 $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
815
816 if( isset($meta['sizes']) && is_array($meta['sizes']) )
817 {
818 foreach( $meta['sizes'] as $k => $v )
819 {
820 if( !isset($response['sizes'][ $k ]) )
821 {
822 $response['sizes'][ $k ] = array(
823 'height' => $v['height'],
824 'width' => $v['width'],
825 'url' => $base_url . $v['file'],
826 'orientation' => $v['height'] > $v['width'] ? 'portrait' : 'landscape',
827 );
828 }
829 }
830 }
831
832 return $response;
833 }
834
835
836 /*
837 * update_value()
838 *
839 * This filter is appied to the $value before it is updated in the db
840 *
841 * @type filter
842 * @since 3.6
843 * @date 23/01/13
844 *
845 * @param $value - the value which will be saved in the database
846 * @param $post_id - the $post_id of which the value will be saved
847 * @param $field - the field array holding all the field options
848 *
849 * @return $value - the modified value
850 */
851
852 function update_value( $value, $post_id, $field )
853 {
854 // array?
855 if( is_array($value) && isset($value['id']) )
856 {
857 $value = $value['id'];
858 }
859
860 // object?
861 if( is_object($value) && isset($value->ID) )
862 {
863 $value = $value->ID;
864 }
865
866 return $value;
867 }
868
869
870 }
871
872 new acf_field_image();
873
874 ?>