PageRenderTime 54ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/advanced-custom-fields/core/fields/image.php

https://bitbucket.org/geetharani/gordon
PHP | 805 lines | 427 code | 197 blank | 181 comment | 41 complexity | 2ba6e523b225daf6c81baa74b2cf103e MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. class acf_Image extends acf_Field
  3. {
  4. /*--------------------------------------------------------------------------------------
  5. *
  6. * Constructor
  7. *
  8. * @author Elliot Condon
  9. * @since 1.0.0
  10. * @updated 2.2.0
  11. *
  12. *-------------------------------------------------------------------------------------*/
  13. function __construct($parent)
  14. {
  15. parent::__construct($parent);
  16. $this->name = 'image';
  17. $this->title = __('Image','acf');
  18. add_action('admin_head-media-upload-popup', array($this, 'popup_head'));
  19. add_filter('get_media_item_args', array($this, 'allow_img_insertion'));
  20. add_action('acf_head-update_attachment-image', array($this, 'acf_head_update_attachment'));
  21. add_action('wp_ajax_acf/fields/image/get_images', array($this, 'ajax_get_images'));
  22. //add_filter('image_size_names_choose', array($this, 'image_size_names_choose'));
  23. add_action('wp_prepare_attachment_for_js', array($this, 'wp_prepare_attachment_for_js'), 10, 3);
  24. }
  25. /*
  26. * acf_head_update_attachment
  27. *
  28. * @description:
  29. * @since: 3.2.7
  30. * @created: 4/07/12
  31. */
  32. function acf_head_update_attachment()
  33. {
  34. ?>
  35. <script type="text/javascript">
  36. (function($){
  37. // vars
  38. var div = self.parent.acf.media.div;
  39. // add message
  40. self.parent.acf.helpers.add_message("<?php _e("Image Updated.",'acf'); ?>", div);
  41. })(jQuery);
  42. </script>
  43. <?php
  44. }
  45. /*
  46. * ajax_get_images
  47. *
  48. * @description:
  49. * @since: 3.5.7
  50. * @created: 13/01/13
  51. */
  52. function ajax_get_images()
  53. {
  54. // vars
  55. $options = array(
  56. 'nonce' => '',
  57. 'images' => array(),
  58. 'preview_size' => 'thumbnail'
  59. );
  60. $return = array();
  61. // load post options
  62. $options = array_merge($options, $_POST);
  63. // verify nonce
  64. if( ! wp_verify_nonce($options['nonce'], 'acf_nonce') )
  65. {
  66. die(0);
  67. }
  68. if( $options['images'] )
  69. {
  70. foreach( $options['images'] as $id )
  71. {
  72. $src = wp_get_attachment_image_src( $id, $options['preview_size'] );
  73. $return[] = array(
  74. 'id' => $id,
  75. 'src' => $src[0],
  76. );
  77. }
  78. }
  79. // return json
  80. echo json_encode( $return );
  81. die;
  82. }
  83. /*--------------------------------------------------------------------------------------
  84. *
  85. * admin_print_scripts / admin_print_styles
  86. *
  87. * @author Elliot Condon
  88. * @since 3.0.1
  89. *
  90. *-------------------------------------------------------------------------------------*/
  91. function allow_img_insertion($vars)
  92. {
  93. $vars['send'] = true;
  94. return($vars);
  95. }
  96. /*--------------------------------------------------------------------------------------
  97. *
  98. * create_field
  99. *
  100. * @author Elliot Condon
  101. * @since 2.0.5
  102. * @updated 2.2.0
  103. *
  104. *-------------------------------------------------------------------------------------*/
  105. function create_field($field)
  106. {
  107. // vars
  108. $class = "";
  109. $file_src = "";
  110. $preview_size = isset($field['preview_size']) ? $field['preview_size'] : 'thumbnail';
  111. // get image url
  112. if($field['value'] != '' && is_numeric($field['value']))
  113. {
  114. $file_src = wp_get_attachment_image_src($field['value'], $preview_size);
  115. $file_src = $file_src[0];
  116. if($file_src)
  117. {
  118. $class = "active";
  119. }
  120. }
  121. ?>
  122. <div class="acf-image-uploader clearfix <?php echo $class; ?>" data-preview_size="<?php echo $preview_size; ?>">
  123. <input class="acf-image-value" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo $field['value']; ?>" />
  124. <div class="has-image">
  125. <div class="hover">
  126. <ul class="bl">
  127. <li><a class="acf-button-delete ir" href="#"><?php _e("Remove",'acf'); ?></a></li>
  128. <li><a class="acf-button-edit ir" href="#"><?php _e("Edit",'acf'); ?></a></li>
  129. </ul>
  130. </div>
  131. <img src="<?php echo $file_src; ?>" alt=""/>
  132. </div>
  133. <div class="no-image">
  134. <p><?php _e('No image selected','acf'); ?> <input type="button" class="button add-image" value="<?php _e('Add Image','acf'); ?>" />
  135. </div>
  136. </div>
  137. <?php
  138. }
  139. /*--------------------------------------------------------------------------------------
  140. *
  141. * create_options
  142. *
  143. * @author Elliot Condon
  144. * @since 2.0.6
  145. * @updated 2.2.0
  146. *
  147. *-------------------------------------------------------------------------------------*/
  148. function create_options($key, $field)
  149. {
  150. // vars
  151. $defaults = array(
  152. 'save_format' => 'id',
  153. 'preview_size' => 'thumbnail',
  154. );
  155. $field = array_merge($defaults, $field);
  156. ?>
  157. <tr class="field_option field_option_<?php echo $this->name; ?>">
  158. <td class="label">
  159. <label><?php _e("Return Value",'acf'); ?></label>
  160. </td>
  161. <td>
  162. <?php
  163. do_action('acf/create_field', array(
  164. 'type' => 'radio',
  165. 'name' => 'fields['.$key.'][save_format]',
  166. 'value' => $field['save_format'],
  167. 'layout' => 'horizontal',
  168. 'choices' => array(
  169. 'object' => __("Image Object",'acf'),
  170. 'url' => __("Image URL",'acf'),
  171. 'id' => __("Image ID",'acf')
  172. )
  173. ));
  174. ?>
  175. </td>
  176. </tr>
  177. <tr class="field_option field_option_<?php echo $this->name; ?>">
  178. <td class="label">
  179. <label><?php _e("Preview Size",'acf'); ?></label>
  180. </td>
  181. <td>
  182. <?php
  183. $image_sizes = $this->parent->get_all_image_sizes();
  184. do_action('acf/create_field', array(
  185. 'type' => 'radio',
  186. 'name' => 'fields['.$key.'][preview_size]',
  187. 'value' => $field['preview_size'],
  188. 'layout' => 'horizontal',
  189. 'choices' => $image_sizes
  190. ));
  191. ?>
  192. </td>
  193. </tr>
  194. <?php
  195. }
  196. /*
  197. * popup_head
  198. *
  199. * @description: css + js for thickbox
  200. * @since: 1.1.4
  201. * @created: 7/12/12
  202. */
  203. function popup_head()
  204. {
  205. // options
  206. $defaults = array(
  207. 'acf_type' => '',
  208. 'acf_preview_size' => 'thumbnail',
  209. 'tab' => 'type',
  210. );
  211. $options = array_merge($defaults, $_GET);
  212. // validate
  213. if( $options['acf_type'] != 'image' )
  214. {
  215. return;
  216. }
  217. // update attachment
  218. if( isset($_POST["attachments"]) )
  219. {
  220. echo '<div class="updated"><p>' . __("Media attachment updated.") . '</p></div>';
  221. }
  222. ?><style type="text/css">
  223. #media-upload-header #sidemenu li#tab-type_url,
  224. #media-items .media-item a.toggle,
  225. #media-items .media-item tr.image-size,
  226. #media-items .media-item tr.align,
  227. #media-items .media-item tr.url,
  228. #media-items .media-item .slidetoggle {
  229. display: none !important;
  230. }
  231. #media-items .media-item {
  232. position: relative;
  233. overflow: hidden;
  234. }
  235. #media-items .media-item .acf-checkbox {
  236. float: left;
  237. margin: 28px 10px 0;
  238. }
  239. #media-items .media-item .pinkynail {
  240. max-width: 64px;
  241. max-height: 64px;
  242. display: block !important;
  243. margin: 2px;
  244. }
  245. #media-items .media-item .filename.new {
  246. min-height: 0;
  247. padding: 20px 10px 10px 10px;
  248. line-height: 15px;
  249. }
  250. #media-items .media-item .title {
  251. line-height: 14px;
  252. }
  253. #media-items .media-item .acf-select {
  254. float: right;
  255. margin: 22px 12px 0 10px;
  256. }
  257. #media-upload .ml-submit {
  258. display: none !important;
  259. }
  260. #media-upload .acf-submit {
  261. margin: 1em 0;
  262. padding: 1em 0;
  263. position: relative;
  264. overflow: hidden;
  265. display: none; /* default is hidden */
  266. clear: both;
  267. }
  268. #media-upload .acf-submit a {
  269. float: left;
  270. margin: 0 10px 0 0;
  271. }
  272. <?php if( $options['tab'] == 'gallery' ): ?>
  273. #sort-buttons,
  274. #gallery-form > .widefat,
  275. #media-items .menu_order,
  276. #gallery-settings {
  277. display: none !important;
  278. }
  279. <?php endif; ?>
  280. </style>
  281. <script type="text/javascript">
  282. (function($){
  283. /*
  284. * Select Image
  285. *
  286. * @description:
  287. * @since: 2.0.4
  288. * @created: 11/12/12
  289. */
  290. $('#media-items .media-item a.acf-select').live('click', function(){
  291. var id = $(this).attr('href');
  292. // IE7 Fix
  293. if( id.indexOf("/") != -1 )
  294. {
  295. var split = id.split("/");
  296. id = split[split.length-1];
  297. }
  298. var ajax_data = {
  299. action : 'acf/fields/image/get_images',
  300. nonce : self.parent.acf.nonce,
  301. images : [ id ],
  302. preview_size : "<?php echo $options['acf_preview_size']; ?>"
  303. };
  304. // ajax
  305. $.ajax({
  306. url: ajaxurl,
  307. type: 'post',
  308. data : ajax_data,
  309. cache: false,
  310. dataType: "json",
  311. success: function( json ) {
  312. // validate
  313. if( !json )
  314. {
  315. return false;
  316. }
  317. // add file
  318. self.parent.acf.fields.image.add( json[0] );
  319. self.parent.tb_remove();
  320. }
  321. });
  322. return false;
  323. });
  324. /*
  325. * Select Images
  326. *
  327. * @description:
  328. * @since: 2.0.4
  329. * @created: 11/12/12
  330. */
  331. $('#acf-add-selected').live('click', function(){
  332. // check total
  333. var total = $('#media-items .media-item .acf-checkbox:checked').length;
  334. if( total == 0 )
  335. {
  336. alert("<?php _e("No images selected",'acf'); ?>");
  337. return false;
  338. }
  339. var ajax_data = {
  340. action : 'acf/fields/image/get_images',
  341. nonce : self.parent.acf.nonce,
  342. images : [],
  343. preview_size : "<?php echo $options['acf_preview_size']; ?>"
  344. };
  345. // add to id array
  346. $('#media-items .media-item .acf-checkbox:checked').each(function(){
  347. ajax_data.images.push( $(this).val() );
  348. });
  349. // ajax
  350. $.ajax({
  351. url: ajaxurl,
  352. type: 'post',
  353. data : ajax_data,
  354. cache: false,
  355. dataType: "json",
  356. success: function( json ) {
  357. // validate
  358. if( !json )
  359. {
  360. return false;
  361. }
  362. var selection = json,
  363. i = 0;
  364. $.each( json, function( k, image ){
  365. // counter
  366. i++;
  367. // vars
  368. var div = self.parent.acf.media.div;
  369. // add image to field
  370. self.parent.acf.fields.image.add( image );
  371. // select / add another file field?
  372. if( i < selection.length )
  373. {
  374. var tr = div.closest('tr'),
  375. repeater = tr.closest('.repeater');
  376. if( tr.next('.row').exists() )
  377. {
  378. self.parent.acf.media.div = tr.next('.row').find('.acf-image-uploader');
  379. }
  380. else
  381. {
  382. // add row
  383. repeater.find('.add-row-end').trigger('click');
  384. // set div to new row file
  385. self.parent.acf.media.div = repeater.find('> table > tbody > tr.row:last .acf-image-uploader');
  386. }
  387. }
  388. });
  389. self.parent.tb_remove();
  390. }
  391. });
  392. return false;
  393. });
  394. /*
  395. * Edit Attachment Toggle
  396. *
  397. * @description:
  398. * @since: 2.0.4
  399. * @created: 11/12/12
  400. */
  401. $('#media-items .media-item a.acf-toggle-edit').live('click', function(){
  402. // vars
  403. var a = $(this),
  404. item = a.closest('.media-item');
  405. // toggle
  406. if( a.hasClass('active') )
  407. {
  408. a.removeClass('active');
  409. item.find('.slidetoggle').attr('style', 'display: none !important');
  410. }
  411. else
  412. {
  413. a.addClass('active');
  414. item.find('.slidetoggle').attr('style', 'display: table !important');
  415. }
  416. // return
  417. return false;
  418. });
  419. /*
  420. * add_buttons
  421. *
  422. * @description:
  423. * @since: 2.0.4
  424. * @created: 11/12/12
  425. */
  426. function add_buttons()
  427. {
  428. // vars
  429. var is_sub_field = (self.parent.acf.media.div.closest('.repeater').length > 0) ? true : false;
  430. // add submit after media items (on for sub fields)
  431. if($('.acf-submit').length == 0 && is_sub_field)
  432. {
  433. $('#media-items').after('<div class="acf-submit"><a id="acf-add-selected" class="button"><?php _e("Add Selected Images",'acf'); ?></a></div>');
  434. }
  435. // add buttons to media items
  436. $('#media-items .media-item:not(.acf-active)').each(function(){
  437. // show the add all button
  438. $('.acf-submit').show();
  439. // needs attachment ID
  440. if($(this).children('input[id*="type-of-"]').length == 0){ return false; }
  441. // only once!
  442. $(this).addClass('acf-active');
  443. // find id
  444. var id = $(this).children('input[id*="type-of-"]').attr('id').replace('type-of-', '');
  445. // if inside repeater, add checkbox
  446. if(is_sub_field)
  447. {
  448. $(this).prepend('<input type="checkbox" class="acf-checkbox" value="' + id + '" <?php if( $options['tab'] == "type" ){echo 'checked="checked"';} ?> />');
  449. }
  450. // Add edit button
  451. $(this).find('.filename.new').append('<br /><a href="#" class="acf-toggle-edit">Edit</a>');
  452. // Add select button
  453. $(this).find('.filename.new').before('<a href="' + id + '" class="button acf-select"><?php _e("Select Image",'acf'); ?></a>');
  454. // add save changes button
  455. $(this).find('tr.submit input.button').hide().before('<input type="submit" value="<?php _e("Update Image",'acf'); ?>" class="button savebutton" />');
  456. });
  457. }
  458. <?php
  459. // run the acf_add_buttons ever 500ms when on the image upload tab
  460. if( $options['tab'] == "type" ): ?>
  461. var acf_t = setInterval(function(){
  462. add_buttons();
  463. }, 500);
  464. <?php endif; ?>
  465. // add acf input filters to allow for tab navigation
  466. $(document).ready(function(){
  467. setTimeout(function(){
  468. add_buttons();
  469. }, 1);
  470. $('form#filter').each(function(){
  471. $(this).append('<input type="hidden" name="acf_preview_size" value="<?php echo $options['acf_preview_size']; ?>" />');
  472. $(this).append('<input type="hidden" name="acf_type" value="image" />');
  473. });
  474. $('form#image-form, form#library-form').each(function(){
  475. var action = $(this).attr('action');
  476. action += "&acf_type=image&acf_preview_size=<?php echo $options['acf_preview_size']; ?>";
  477. $(this).attr('action', action);
  478. });
  479. <?php
  480. // add support for media tags
  481. if( $options['tab'] == 'mediatags' ): ?>
  482. $('#media-items .mediatag-item-count a').each(function(){
  483. var href = $(this).attr('href');
  484. href += "&acf_type=image&acf_preview_size=<?php echo $options['acf_preview_size']; ?>";
  485. $(this).attr('href', href);
  486. });
  487. <?php endif; ?>
  488. });
  489. })(jQuery);
  490. </script><?php
  491. }
  492. /*--------------------------------------------------------------------------------------
  493. *
  494. * get_value_for_api
  495. *
  496. * @author Elliot Condon
  497. * @since 3.0.0
  498. *
  499. *-------------------------------------------------------------------------------------*/
  500. function get_value_for_api($post_id, $field)
  501. {
  502. // vars
  503. $format = isset($field['save_format']) ? $field['save_format'] : 'url';
  504. $value = parent::get_value($post_id, $field);
  505. // validate
  506. if( !$value )
  507. {
  508. return false;
  509. }
  510. // format
  511. if($format == 'url')
  512. {
  513. $value = wp_get_attachment_url($value);
  514. }
  515. elseif($format == 'object')
  516. {
  517. $attachment = get_post( $value );
  518. // validate
  519. if( !$attachment )
  520. {
  521. return false;
  522. }
  523. // create array to hold value data
  524. $value = array(
  525. 'id' => $attachment->ID,
  526. 'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
  527. 'title' => $attachment->post_title,
  528. 'caption' => $attachment->post_excerpt,
  529. 'description' => $attachment->post_content,
  530. 'url' => wp_get_attachment_url( $attachment->ID ),
  531. 'sizes' => array(),
  532. );
  533. // find all image sizes
  534. $image_sizes = get_intermediate_image_sizes();
  535. if( $image_sizes )
  536. {
  537. foreach( $image_sizes as $image_size )
  538. {
  539. // find src
  540. $src = wp_get_attachment_image_src( $attachment->ID, $image_size );
  541. // add src
  542. $value['sizes'][$image_size] = $src[0];
  543. }
  544. // foreach( $image_sizes as $image_size )
  545. }
  546. // if( $image_sizes )
  547. }
  548. return $value;
  549. }
  550. /*
  551. * image_size_names_choose
  552. *
  553. * @description:
  554. * @since: 3.5.7
  555. * @created: 13/01/13
  556. */
  557. function image_size_names_choose( $sizes )
  558. {
  559. global $_wp_additional_image_sizes;
  560. if( $_wp_additional_image_sizes )
  561. {
  562. foreach( $_wp_additional_image_sizes as $k => $v )
  563. {
  564. $title = $k;
  565. $title = str_replace('-', ' ', $title);
  566. $title = str_replace('_', ' ', $title);
  567. $title = ucwords( $title );
  568. $sizes[ $k ] = $title;
  569. }
  570. // foreach( $image_sizes as $image_size )
  571. }
  572. return $sizes;
  573. }
  574. /*
  575. * wp_prepare_attachment_for_js
  576. *
  577. * @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
  578. * @since: 3.5.7
  579. * @created: 13/01/13
  580. */
  581. function wp_prepare_attachment_for_js( $response, $attachment, $meta )
  582. {
  583. // only for image
  584. if( $response['type'] != 'image' )
  585. {
  586. return $response;
  587. }
  588. $attachment_url = $response['url'];
  589. $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
  590. if( is_array($meta['sizes']) )
  591. {
  592. foreach( $meta['sizes'] as $k => $v )
  593. {
  594. if( !isset($response['sizes'][ $k ]) )
  595. {
  596. $response['sizes'][ $k ] = array(
  597. 'height' => $v['height'],
  598. 'width' => $v['width'],
  599. 'url' => $base_url . $v['file'],
  600. 'orientation' => $v['height'] > $v['width'] ? 'portrait' : 'landscape',
  601. );
  602. }
  603. }
  604. }
  605. return $response;
  606. }
  607. }
  608. ?>