PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/file-gallery/includes/attachments.php

https://bitbucket.org/Wallynm/iptb
PHP | 783 lines | 528 code | 180 blank | 75 comment | 126 complexity | 5240bb2074239c0442ea5e03dcd63697 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0, GPL-2.0, GPL-3.0
  1. <?php
  2. function file_gallery_check_attachment_originality()
  3. {
  4. global $wp_query, $wpdb;
  5. if( 'upload' == get_current_screen()->base && ! empty($wp_query->posts) )
  6. {
  7. $ids = array();
  8. $copies = array();
  9. $originals = array();
  10. foreach( $wp_query->posts as $post )
  11. {
  12. $ids[] = $post->ID;
  13. }
  14. if( ! empty($ids) && $results = $wpdb->get_results("SELECT post_id, meta_key FROM $wpdb->postmeta WHERE meta_key IN ('_has_copies', '_is_copy_of') AND post_id IN ('" . implode("', '", $ids) . "')") )
  15. {
  16. foreach( $results as $r )
  17. {
  18. if( '_has_copies' == $r->meta_key )
  19. $originals[] = $r->post_id;
  20. if( '_is_copy_of' == $r->meta_key )
  21. $copies[] = $r->post_id;
  22. }
  23. }
  24. if( ! empty($originals) || ! empty($copies) )
  25. {
  26. if( ! empty($originals) )
  27. $originals = '"#post-' . implode(', #post-', $originals) . '"';
  28. else
  29. $originals = 'null';
  30. if( ! empty($copies) )
  31. $copies = '"#post-' . implode(', #post-', $copies) . '"';
  32. else
  33. $copies = 'null';
  34. ?>
  35. <script type="text/javascript">
  36. var file_gallery_originals = <?php echo $originals; ?>,
  37. file_gallery_copies = <?php echo $copies; ?>;
  38. if( null !== file_gallery_originals)
  39. jQuery(file_gallery_originals).addClass("attachment-original");
  40. if( null !== file_gallery_copies)
  41. jQuery(file_gallery_copies).addClass("attachment-copy");
  42. </script>
  43. <?php
  44. }
  45. }
  46. }
  47. add_action( 'admin_footer', 'file_gallery_check_attachment_originality' );
  48. /**
  49. * Prepares attachment data to be sent to the WordPress text editor
  50. *
  51. * This function is used via AJAX and works with
  52. * POST data. The only required variable is the ID
  53. * of the attachment(s) ("attachment_id").
  54. *
  55. * No parameters
  56. * @return echoes attachment data as HTML
  57. * with {@link file_gallery_parse_attachment_data()}
  58. */
  59. function file_gallery_get_attachment_data()
  60. {
  61. global $file_gallery;
  62. check_ajax_referer('file-gallery');
  63. $attachment = $_POST['attachment_id'];
  64. $size = $_POST['size'];
  65. $linkto = $_POST['linkto'];
  66. $external_url = $_POST['external_url'];
  67. $linkclass = $_POST['linkclass'];
  68. $imageclass = $_POST['imageclass'];
  69. $align = $_POST['align'];
  70. $rel = '';
  71. $_caption = ('true' == $_POST['caption'] || '1' == $_POST['caption']) ? true : false;
  72. if( 'external_url' == $linkto )
  73. $linkto = $external_url;
  74. if( 'undefined' == $linkclass || '' == $linkclass )
  75. $linkclass = '';
  76. if( 'undefined' == $imageclass || '' == $imageclass )
  77. $imageclass = '';
  78. if( 'undefined' == $align || '' == $align )
  79. $align = 'none';
  80. $attachments = explode(',', $attachment);
  81. if( 1 < count($attachments) && '' != $linkclass && ! in_array($linkto, array('attachment', 'parent_post', 'none')) )
  82. {
  83. if( ! isset($file_gallery->gallery_id) )
  84. $file_gallery->gallery_id = 1;
  85. else
  86. $file_gallery->gallery_id++;
  87. $rel = ' rel="' . $linkclass . '[' . $file_gallery->gallery_id . ']"';
  88. }
  89. foreach( $attachments as $attachment_id )
  90. {
  91. $caption = $_caption;
  92. $attachment = get_post($attachment_id);
  93. $excerpt = trim($attachment->post_excerpt);
  94. if( true === $caption )
  95. $caption = '' != $excerpt ? $excerpt : false;
  96. if( false === $caption )
  97. $imageclass .= ' align' . $align;
  98. $imageclass .= ' size-' . $size;
  99. if( (1 === count($attachments) || (1 < count($attachments) && '' == $linkclass)) && 'attachment' == $linkto )
  100. $rel = ' rel="attachment wp-att-' . $attachment->ID . '"';
  101. echo file_gallery_parse_attachment_data( $attachment, $size, $linkto, $linkclass, $imageclass, $rel, $caption, $align );
  102. }
  103. exit();
  104. }
  105. add_action('wp_ajax_file_gallery_send_single', 'file_gallery_get_attachment_data');
  106. /**
  107. * Transforms attachment data into HTML
  108. *
  109. * @param int $attachment_id ID of the attachment
  110. * @return mixed Returns a HTML string, or FALSE if $attachment_id is not a number
  111. */
  112. function file_gallery_parse_attachment_data( $attachment, $size, $linkto, $linkclass, $imageclass, $rel, $caption, $align )
  113. {
  114. global $wpdb;
  115. if( ! is_numeric($attachment->ID) )
  116. return false; // not a number, exiting
  117. $link = '';
  118. if( ! $thumb_alt = get_post_meta($attachment->ID, '_wp_attachment_image_alt', true) )
  119. $thumb_alt = $attachment->post_title;
  120. $title = $attachment->post_title;
  121. if( file_gallery_file_is_displayable_image( get_attached_file($attachment->ID) ) )
  122. {
  123. $size_src = wp_get_attachment_image_src($attachment->ID, $size, false);
  124. $width = $size_src[1];
  125. $height = $size_src[2];
  126. $size_src = $size_src[0];
  127. $imageclass .= ' wp-image-' . $attachment->ID;
  128. }
  129. else
  130. {
  131. $filetype = file_gallery_get_file_type($attachment->post_mime_type);
  132. $size_src = FILE_GALLERY_CRYSTAL_URL . '/' . $filetype . '.png';
  133. $width = '';
  134. $height = '';
  135. $imageclass .= ' non-image';
  136. }
  137. $output = '<img src="' . $size_src . '" alt="' . $thumb_alt . '" title="' . $title . '" width="' . $width . '" height="' . $height . '" class="' . trim($imageclass) . '" />';
  138. switch( $linkto )
  139. {
  140. case 'parent_post' :
  141. $link = get_permalink( $wpdb->get_var("SELECT `post_parent` FROM $wpdb->posts WHERE ID = '" . $attachment->ID . "'") );
  142. break;
  143. case 'file' :
  144. $link = wp_get_attachment_url( $attachment->ID );
  145. break;
  146. case 'attachment' :
  147. $link = get_attachment_link( $attachment->ID );
  148. break;
  149. case 'none' :
  150. $link = '';
  151. break;
  152. default : // external url
  153. $link = urldecode($linkto);
  154. break;
  155. }
  156. if( '' != $link )
  157. {
  158. if( '' != trim($linkclass) )
  159. $linkclass = ' class="' . trim($linkclass) . '"';
  160. $output = '<a href="' . $link . '"' . $linkclass . $rel . '>' . $output . '</a>' . "\n\n";
  161. }
  162. if( false !== $caption )
  163. {
  164. $output = '[caption id="attachment_' . $attachment->ID . '" align="align' . $align . '" width="' . $width . '" caption="' . $caption .'"]' . trim($output) . '[/caption]' . "\n\n";
  165. }
  166. return apply_filters('file_gallery_parse_attachment_data', $output, $attachment->ID);
  167. }
  168. /**
  169. * Soon...
  170. */
  171. function file_gallery_caption_shortcode( $output = "", $attr, $content = null)
  172. {
  173. extract(
  174. shortcode_atts(
  175. array(
  176. 'id' => '',
  177. 'align' => 'alignnone',
  178. 'width' => '',
  179. 'caption' => ''
  180. ), $attr));
  181. if ( 1 > (int) $width || empty($caption) )
  182. return $content;
  183. if ( $id )
  184. $id = 'id="' . esc_attr($id) . '" ';
  185. $caption = urldecode($caption);
  186. return '<div ' . $id . 'class="wp-caption ' . esc_attr($align) . '" style="width: ' . (10 + (int) $width) . 'px">'
  187. . do_shortcode( $content ) . '<p class="wp-caption-text">' . $caption . '</p></div>';
  188. }
  189. //add_filter('img_caption_shortcode', 'file_gallery_caption_shortcode', 10, 3);
  190. /**
  191. * This function displays attachment data inside an HTML
  192. * form. It allows attachment data to be viewed as well as edited.
  193. */
  194. function file_gallery_edit_attachment()
  195. {
  196. check_ajax_referer('file-gallery');
  197. $type = 'image';
  198. $media_tags = array();
  199. $options = get_option('file_gallery');
  200. $attachment_id = (int) $_POST['attachment_id'];
  201. $attachment = get_post( $attachment_id );
  202. if( ! $attachment )
  203. {
  204. printf( __('Attachment with ID <strong>%d</strong> does not exist!', 'file-gallery'), $attachment_id );
  205. exit();
  206. }
  207. if( file_gallery_file_is_displayable_image( get_attached_file($attachment->ID) ) )
  208. {
  209. $fullsize_src = wp_get_attachment_image_src( $attachment->ID, 'large', false );
  210. $fullsize_src = $fullsize_src[0];
  211. $size_src = wp_get_attachment_image_src( $attachment->ID, 'medium', false );
  212. $size_src = $size_src[0];
  213. }
  214. else
  215. {
  216. $fullsize_src = wp_get_attachment_url( $attachment->ID );
  217. $size_src = file_gallery_https( FILE_GALLERY_CRYSTAL_URL ) . '/' . file_gallery_get_file_type($attachment->post_mime_type) . '.png';
  218. $type = 'document';
  219. }
  220. $post_author = get_userdata($attachment->post_author);
  221. $post_author = $post_author->user_nicename;
  222. $tags = wp_get_object_terms( $attachment->ID, FILE_GALLERY_MEDIA_TAG_NAME );
  223. foreach( $tags as $tag )
  224. {
  225. $media_tags[] = $tag->name;
  226. }
  227. $media_tags = implode(', ', $media_tags);
  228. $has_copies = maybe_unserialize(get_post_meta($attachment->ID, '_has_copies', true));
  229. $is_copy = get_post_meta($attachment->ID, '_is_copy_of', true);
  230. do_action('file_gallery_edit_attachment', $attachment->ID);
  231. ?>
  232. <div id="file_gallery_attachment_edit_image">
  233. <?php if( 'image' == $type ) : ?>
  234. <a href="<?php echo $fullsize_src; ?>" title="" class="attachment_edit_thumb"><img src="<?php echo $size_src; ?>" alt="image" /></a>
  235. <p>
  236. <a href="#" id="regenerate[<?php echo $attachment->ID; ?>]" class="file_gallery_regenerate"><?php _e("Regenerate this image's thumbnails", "file-gallery"); ?></a>
  237. </p>
  238. <?php else : ?>
  239. <img src="<?php echo $size_src; ?>" alt="image" />
  240. <?php endif; ?>
  241. <br />
  242. <div id="attachment_data">
  243. <p><strong><?php _e('ID:', 'file-gallery'); ?></strong> <a href="<?php echo admin_url('media.php?attachment_id=' . $attachment->ID . '&action=edit&TB_iframe=1'); ?>" class="thickbox" onclick="return false;"><?php echo $attachment->ID; ?></a></p>
  244. <p><strong><?php _e('Date uploaded:', 'file-gallery'); ?></strong><br /><?php echo date(get_option('date_format'), strtotime($attachment->post_date)); ?></p>
  245. <p><strong><?php _e('Uploaded by:', 'file-gallery'); ?></strong> <?php echo $post_author; ?></p>
  246. <?php if( is_array($has_copies) ) : ?>
  247. <p class="attachment_info_has_copies"><?php _e('IDs of copies of this attachment:', 'file-gallery'); ?> <strong><?php foreach( $has_copies as $c){ echo '<a href="' . admin_url('media.php?attachment_id=' . $c . '&action=edit') . '" target="_blank">' . $c . '</a>'; }?></strong></p>
  248. <?php endif; ?>
  249. <?php if( $is_copy ) : ?>
  250. <p class="attachment_info_is_a_copy"><?php _e('This attachment is a copy of attachment ID', 'file-gallery'); ?> <strong><?php echo '<a href="' . admin_url('media.php?attachment_id=' . $is_copy . '&action=edit') . '" target="_blank">' . $is_copy . '</a>'; ?></strong></p>
  251. <?php endif; ?>
  252. </div>
  253. </div>
  254. <?php do_action('file_gallery_pre_edit_attachment_post_form', $attachment->ID); ?>
  255. <div id="attachment_data_edit_form">
  256. <input type="hidden" name="post_id" id="fgae_post_id" value="<?php echo $_POST['post_id']; ?>" />
  257. <input type="hidden" name="attachment_id" id="fgae_attachment_id" value="<?php echo $_POST['attachment_id']; ?>" />
  258. <input type="hidden" name="attachment_order" id="fgae_attachment_order" value="<?php echo $_POST['attachment_order']; ?>" />
  259. <input type="hidden" name="checked_attachments" id="fgae_checked_attachments" value="<?php echo $_POST['checked_attachments']; ?>" />
  260. <input type="hidden" name="action" id="fgae_action" value="update" />
  261. <?php if( file_gallery_file_is_displayable_image( get_attached_file($attachment->ID) ) ) : ?>
  262. <label for="post_alt"><?php _e('Alternate text for this image', 'file-gallery'); ?>: </label>
  263. <input type="text" name="post_alt" id="fgae_post_alt" value="<?php echo get_post_meta($attachment->ID, '_wp_attachment_image_alt', true); ?>" class="roundborder"<?php if( ! current_user_can('edit_post', $attachment->ID)){ echo ' readonly="readonly"';} ?> /><br />
  264. <?php endif; ?>
  265. <label for="post_title"><?php _e('Title', 'file-gallery'); ?>: </label>
  266. <input type="text" name="post_title" id="fgae_post_title" value="<?php echo $attachment->post_title; ?>" class="roundborder"<?php if( ! current_user_can('edit_post', $attachment->ID) ){ echo ' readonly="readonly"';} ?> /><br />
  267. <label for="post_excerpt"><?php _e('Caption', 'file-gallery'); ?>: </label>
  268. <textarea name="post_excerpt" id="fgae_post_excerpt" class="roundborder"<?php if( ! current_user_can('edit_post', $attachment->ID) ){ echo ' readonly="readonly"';} ?>><?php echo $attachment->post_excerpt; ?></textarea><br />
  269. <label for="post_content"><?php _e('Description', 'file-gallery'); ?>: </label>
  270. <textarea name="post_content" id="fgae_post_content" rows="4" cols="20" class="roundborder"<?php if( ! current_user_can('edit_post', $attachment->ID) ){ echo ' readonly="readonly"';} ?>><?php echo $attachment->post_content; ?></textarea><br />
  271. <label for="tax_input"><?php _e('Media tags (separate each tag with a comma)', 'file-gallery'); ?>: </label>
  272. <input type="text" name="tax_input" id="fgae_tax_input" value="<?php echo $media_tags; ?>" class="roundborder"<?php if( ! current_user_can('edit_post', $attachment->ID) ){ echo ' readonly="readonly"';} ?> /><br />
  273. <label for="menu_order"><?php _e('Menu order', 'file-gallery'); ?>: </label>
  274. <input type="text" name="menu_order" id="fgae_menu_order" value="<?php echo $attachment->menu_order; ?>" class="roundborder"<?php if( ! current_user_can('edit_post', $attachment->ID) ){ echo ' readonly="readonly"';} ?> /><br />
  275. <label for="attachment_uri"><?php _e('Attachment file URL:', 'file-gallery'); ?></label>
  276. <input type="text" name="attachment_uri" id="fgae_attachment_uri" readonly="readonly" value="<?php echo $fullsize_src; ?>" class="roundborder" />
  277. <br />
  278. <br />
  279. <?php
  280. if( isset($options['display_acf']) && true == $options['display_acf'] )
  281. file_gallery_attachment_custom_fields_table($attachment->ID);
  282. ?>
  283. <input type="button" id="file_gallery_edit_attachment_save" value="<?php _e('save and return', 'file-gallery'); ?>" class="button-primary" />
  284. <input type="button" id="file_gallery_edit_attachment_cancel"value="<?php _e('cancel and return', 'file-gallery'); ?>" class="button-secondary" />
  285. </div>
  286. <?php
  287. do_action('file_gallery_edit_attachment_post_form', $attachment->ID);
  288. exit();
  289. }
  290. add_action('wp_ajax_file_gallery_edit_attachment', 'file_gallery_edit_attachment');
  291. /**
  292. * Copies an attachment's data and creates a new attachment
  293. * for the current post using that data
  294. */
  295. function file_gallery_copy_attachments_to_post()
  296. {
  297. global $wpdb;
  298. check_ajax_referer('file-gallery-attach');
  299. $post_id = (int) $_POST['post_id'];
  300. $attached_ids = $_POST['ids'];
  301. // get checked attachments
  302. if( "" != $attached_ids )
  303. $possible_new_attachments = get_posts('post_type=attachment&include=' . $attached_ids);
  304. // get current post's attachments
  305. $current_attachments = get_posts('numberposts=-1&post_type=attachment&post_parent=' . $post_id);
  306. if( false !== $current_attachments && ! empty($current_attachments) ) // if post already has attachments
  307. {
  308. foreach( $possible_new_attachments as $pna ) // for each checked item...
  309. {
  310. foreach( $current_attachments as $ca ) // go through each already present attachment
  311. {
  312. if( wp_get_attachment_url($pna->ID) == wp_get_attachment_url($ca->ID) ) // if their URIs match
  313. {
  314. $attached_ids = str_replace( $pna->ID, "", $attached_ids ); // remove that id from the list
  315. $attachments_exist[] = $pna->ID; // and add it to a list of conflicting attachments
  316. }
  317. }
  318. }
  319. }
  320. $attached_ids = preg_replace('#,+#', ',', $attached_ids ); // remove extra commas
  321. if( '' != $attached_ids )
  322. $attached_ids = explode(',', trim($attached_ids, ',')); // explode into array if not empty
  323. // prepare data and copy attachment to current post
  324. if( is_array($attached_ids) )
  325. {
  326. foreach( $attached_ids as $aid )
  327. {
  328. file_gallery_copy_attachment_to_post( $aid, $post_id );
  329. }
  330. // generate output
  331. if( ! empty($attachments_exist) )
  332. {
  333. $output .= __('Some of the checked attachments were successfully attached to current post.', 'file-gallery');
  334. $output .= '<br />' . __("Additionally, here are ID's of attachments you had selected, but were already attached to current post, according to their URIs.<br />You will be presented with an option to copy those attachments as well in the next version of this plugin. If that makes any sense, that is.", 'file-gallery') . ': ' . implode(',', $attachments_exist);
  335. }
  336. else
  337. {
  338. $output .= __('Checked attachments were successfully attached to current post.', 'file-gallery');
  339. }
  340. }
  341. else
  342. {
  343. if( ! empty($attachments_exist) )
  344. $output .= __('All of the checked attachments are already attached to current post, according to their URIs.<br />You will be presented with an option to copy those attachments as well in the next version of this plugin. If that makes any sense, that is.', 'file-gallery');
  345. else
  346. $output .= __('You must check the checkboxes next to attachments you want to copy to current post.', 'file-gallery');
  347. }
  348. if( ! is_array($attached_ids) )
  349. $attached_ids = array();
  350. // return output prepended by a list of checked attachments
  351. // using # (hash) as the separator
  352. echo implode(',', $attached_ids) . '#' . $output;
  353. exit();
  354. }
  355. add_action('wp_ajax_file_gallery_copy_attachments_to_post', 'file_gallery_copy_attachments_to_post');
  356. /**
  357. * Copies an attachment to a post
  358. */
  359. function file_gallery_copy_attachment_to_post( $aid, $post_id )
  360. {
  361. global $wpdb;
  362. if( ! is_numeric($aid) || ! is_numeric($post_id) || 0 === (int) $aid || 0 === (int) $post_id )
  363. return -1;
  364. $attachment = get_post($aid);
  365. // don't duplicate - if it's unattached, just attach it without copying the data
  366. if( 0 === $attachment->post_parent )
  367. return $wpdb->update( $wpdb->posts, array('post_parent' => $post_id), array('ID' => $attachment->ID), array('%d'), array('%d') );
  368. $attachment->metadata = get_post_meta($attachment->ID, '_wp_attachment_metadata', true);
  369. $attachment->attached_file = get_post_meta($attachment->ID, '_wp_attached_file', true);
  370. unset($attachment->ID);
  371. // maybe include this as an option on media settings screen...?
  372. $attachment->post_title .= apply_filters('file_gallery_attachment_copy_title_extension', '', $post_id);
  373. // copy main attachment data
  374. $attachment_id = wp_insert_attachment( $attachment, false, $post_id );
  375. // copy attachment custom fields
  376. $acf = get_post_custom($aid);
  377. foreach( $acf as $key => $val )
  378. {
  379. foreach( $val as $v )
  380. {
  381. add_post_meta($attachment_id, $key, $v);
  382. }
  383. }
  384. // other meta values
  385. update_post_meta( $attachment_id, '_wp_attached_file', $attachment->attached_file );
  386. update_post_meta( $attachment_id, '_wp_attachment_metadata', $attachment->metadata );
  387. /* copies and originals */
  388. // if we're duplicating a copy, set duplicate's "_is_copy_of" value to original's ID
  389. if( $is_a_copy = get_post_meta($aid, '_is_copy_of', true) )
  390. $aid = $is_a_copy;
  391. update_post_meta($attachment_id, '_is_copy_of', $aid);
  392. // meta for the original attachment (array holding ids of its copies)
  393. $has_copies = get_post_meta($aid, '_has_copies', true);
  394. $has_copies[] = $attachment_id;
  395. $has_copies = array_unique($has_copies);
  396. update_post_meta($aid, '_has_copies', $has_copies);
  397. /* / copies and originals */
  398. // copy media tags
  399. $media_tags = wp_get_object_terms(array($aid), FILE_GALLERY_MEDIA_TAG_NAME);
  400. $tags = array();
  401. foreach( $media_tags as $mt )
  402. {
  403. $tags[] = $mt->name;
  404. }
  405. wp_set_object_terms($attachment_id, $tags, FILE_GALLERY_MEDIA_TAG_NAME);
  406. return $attachment_id;
  407. }
  408. /**
  409. * copies all attachments from one post to another
  410. */
  411. function file_gallery_copy_all_attachments()
  412. {
  413. global $wpdb;
  414. $from_id = $_POST['from_id'];
  415. $to_id = $_POST['to_id'];
  416. $thumb_id = false;
  417. if( ! is_numeric($from_id) || ! is_numeric($to_id) || 0 === $from_id || 0 === $to_id )
  418. exit('ID not numeric or zero! (file_gallery_copy_all_attachments)');
  419. $attachments = $wpdb->get_results( sprintf("SELECT `ID` FROM $wpdb->posts WHERE `post_type`='attachment' AND `post_parent`=%d", $from_id) );
  420. if( false === $attachments )
  421. {
  422. $error = __('Database error! (file_gallery_copy_all_attachments)', 'file-gallery');
  423. file_gallery_write_log( $error );
  424. exit( $error );
  425. }
  426. if( 0 === count($attachments) )
  427. exit( sprintf( __('Uh-oh. No attachments were found for post ID %d.', 'file-gallery'), $from_id ) );
  428. // if the post we're copying all the attachments to has no attachments...
  429. if( 0 === count( $wpdb->get_results( $wpdb->prepare("SELECT `ID` FROM $wpdb->posts WHERE `post_type`='attachment' AND `post_parent`=%d", $to_id) ) ) )
  430. $thumb_id = get_post_meta( $from_id, '_thumbnail_id', true ); // ...automatically set the original post's thumb to the new one
  431. do_action('file_gallery_copy_all_attachments', $from_id, $to_id);
  432. foreach( $attachments as $aid )
  433. {
  434. $r = file_gallery_copy_attachment_to_post( $aid->ID, $to_id );
  435. if( -1 === $r )
  436. $errors[] = $aid->ID;
  437. // set post thumb
  438. if( $aid->ID === $thumb_id )
  439. update_post_meta( $to_id, '_thumbnail_id', $r);
  440. }
  441. if( ! isset($errors) )
  442. echo sprintf( __('All attachments were successfully copied from post %d.', 'file-gallery'), $from_id );
  443. else
  444. echo 'error ids: ' . implode(', ', $errors);
  445. exit();
  446. }
  447. add_action('wp_ajax_file_gallery_copy_all_attachments', 'file_gallery_copy_all_attachments');
  448. /**
  449. * This is a copy of wp_delete_attachment function without file deletion bits.
  450. *
  451. * It removes database data only.
  452. */
  453. function file_gallery_delete_attachment( $post_id )
  454. {
  455. global $wpdb;
  456. if ( ! current_user_can('delete_post', $post_id) )
  457. return false;
  458. if ( ! $post = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id) ) )
  459. return $post;
  460. if ( 'attachment' != $post->post_type )
  461. return false;
  462. delete_post_meta($post_id, '_wp_trash_meta_status');
  463. delete_post_meta($post_id, '_wp_trash_meta_time');
  464. do_action('file_gallery_delete_attachment', $post_id);
  465. wp_delete_object_term_relationships($post_id, array('category', 'post_tag'));
  466. wp_delete_object_term_relationships($post_id, get_object_taxonomies($post->post_type));
  467. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id' AND meta_value = %d", $post_id ));
  468. // delete comments
  469. $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ));
  470. if ( ! empty( $comment_ids ) ) {
  471. do_action( 'delete_comment', $comment_ids );
  472. foreach ( $comment_ids as $comment_id )
  473. wp_delete_comment( $comment_id, true );
  474. do_action( 'deleted_comment', $comment_ids );
  475. }
  476. // delete meta values
  477. $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ));
  478. if ( ! empty($post_meta_ids) )
  479. {
  480. do_action( 'delete_postmeta', $post_meta_ids );
  481. $in_post_meta_ids = "'" . implode("', '", $post_meta_ids) . "'";
  482. $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_id IN($in_post_meta_ids)" );
  483. do_action( 'deleted_postmeta', $post_meta_ids );
  484. }
  485. do_action( 'delete_post', $post_id );
  486. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $post_id ));
  487. do_action( 'deleted_post', $post_id );
  488. clean_post_cache($post_id);
  489. return $post;
  490. }
  491. /**
  492. * Cancels deletion of the actual _file_ by returning an empty string as file path
  493. * if the deleted attachment had copies or was a copy itself
  494. */
  495. function file_gallery_cancel_file_deletion_if_attachment_copies( $file )
  496. {
  497. global $wpdb;
  498. if( defined('FILE_GALLERY_SKIP_DELETE_CANCEL') && true === FILE_GALLERY_SKIP_DELETE_CANCEL )
  499. return $file;
  500. $_file = $file;
  501. $was_original = true;
  502. // get '_wp_attached_file' value based on upload path
  503. if( false !== get_option('uploads_use_yearmonth_folders') )
  504. {
  505. $_file = explode('/', $_file);
  506. $c = count($_file);
  507. $_file = $_file[$c-3] . '/' . $_file[$c-2] . '/' . $_file[$c-1];
  508. }
  509. // find all attachments that share the same file
  510. $this_copies = $wpdb->get_col(
  511. $wpdb->prepare(
  512. "SELECT `post_id`
  513. FROM $wpdb->postmeta
  514. WHERE `meta_key` = '_wp_attached_file'
  515. AND `meta_value` = '%s'",
  516. $_file
  517. )
  518. );
  519. if( is_array($this_copies) && ! empty($this_copies) )
  520. {
  521. foreach( $this_copies as $tc ) // determine if original was deleted
  522. {
  523. if( '' != get_post_meta($tc, '_has_copies', true) )
  524. $was_original = false;
  525. }
  526. if( $was_original ) // original is deleted, promote first copy
  527. $promoted_id = file_gallery_promote_first_attachment_copy(0, $this_copies);
  528. $uploadpath = wp_upload_dir();
  529. $file_path = path_join($uploadpath['basedir'], $_file);
  530. if( file_gallery_file_is_displayable_image($file_path) ) // if it's an image - regenerate its intermediate sizes
  531. $regenerate = wp_update_attachment_metadata($promoted_id, wp_generate_attachment_metadata($promoted_id, $file_path));
  532. return '';
  533. }
  534. return $file;
  535. }
  536. add_filter('wp_delete_file', 'file_gallery_cancel_file_deletion_if_attachment_copies');
  537. /**
  538. * Deletes all the copies of the original attachment (database data only, not files)
  539. */
  540. function file_gallery_delete_all_attachment_copies( $attachment_id )
  541. {
  542. $copies = get_post_meta($attachment_id, '_has_copies', true);
  543. if( is_array($copies) && ! empty($copies) )
  544. {
  545. do_action('file_gallery_delete_all_attachment_copies', $attachment_id, &$copies);
  546. foreach( $copies as $copy )
  547. {
  548. file_gallery_delete_attachment( $copy );
  549. }
  550. return $copies;
  551. }
  552. // no copies
  553. return false;
  554. }
  555. function file_gallery_handle_deleted_attachment( $post_id )
  556. {
  557. $is_copy_of = get_post_meta($post_id, '_is_copy_of', true);
  558. if( ! empty($is_copy_of) && is_numeric($is_copy_of) && $copies = get_post_meta($is_copy_of, '_has_copies', true) )
  559. {
  560. foreach( $copies as $k => $v )
  561. {
  562. if( (int) $post_id === (int) $v )
  563. unset($copies[$k]);
  564. }
  565. if( empty($copies) )
  566. delete_post_meta($is_copy_of, '_has_copies');
  567. else
  568. update_post_meta($is_copy_of, '_has_copies', $copies);
  569. }
  570. }
  571. add_action('delete_attachment', 'file_gallery_handle_deleted_attachment');
  572. add_action('file_gallery_delete_attachment', 'file_gallery_handle_deleted_attachment');
  573. /**
  574. * Promotes the first copy of an attachment (probably to be deleted)
  575. * into the original (with other copies becoming its copies now)
  576. */
  577. function file_gallery_promote_first_attachment_copy( $attachment_id, $copies = false )
  578. {
  579. if( false === $copies )
  580. $copies = get_post_meta($attachment_id, '_has_copies', true);
  581. if( is_array($copies) && ! empty($copies) )
  582. {
  583. $promoted_id = array_shift($copies);
  584. do_action('file_gallery_promote_first_attachment_copy', $attachment_id, &$promoted_id);
  585. delete_post_meta($promoted_id, '_is_copy_of');
  586. if( ! empty($copies) )
  587. {
  588. // update promoted attachments meta
  589. add_post_meta($promoted_id, '_has_copies', $copies);
  590. // update copies' meta
  591. foreach( $copies as $copy )
  592. {
  593. update_post_meta($copy, '_is_copy_of', $promoted_id);
  594. }
  595. }
  596. return $promoted_id;
  597. }
  598. // no copies
  599. return false;
  600. }
  601. ?>