PLL_Admin_Filters_Media

Manages filters and actions related to media on admin side Capability to edit / create media is checked before loading this class.

Defined (1)

The class is defined in the following location(s).

/admin/admin-filters-media.php  
  1. class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base { 
  2. /** 
  3. * Constructor: setups filters and actions 
  4. * @since 1.2 
  5. * @param object $polylang 
  6. */ 
  7. public function __construct( &$polylang ) { 
  8. parent::__construct( $polylang ); 
  9.  
  10. // Adds the language field and translations tables in the 'Edit Media' panel 
  11. add_filter( 'attachment_fields_to_edit', array( $this, 'attachment_fields_to_edit' ), 10, 2 ); 
  12.  
  13. // Adds actions related to languages when creating, saving or deleting media 
  14. add_action( 'add_attachment', array( $this, 'set_default_language' ) ); 
  15. add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 ); 
  16. add_filter( 'wp_delete_file', array( $this, 'wp_delete_file' ) ); 
  17.  
  18. // Creates a media translation 
  19. if ( isset( $_GET['action'], $_GET['new_lang'], $_GET['from_media'] ) && 'translate_media' === $_GET['action'] ) { 
  20. add_action( 'admin_init', array( $this, 'translate_media' ) ); 
  21.  
  22. /** 
  23. * Adds the language field and translations tables in the 'Edit Media' panel 
  24. * Needs WP 3.5+ 
  25. * @since 0.9 
  26. * @param array $fields list of form fields 
  27. * @param object $post 
  28. * @return array modified list of form fields 
  29. */ 
  30. public function attachment_fields_to_edit( $fields, $post ) { 
  31. if ( 'post.php' == $GLOBALS['pagenow'] ) { 
  32. return $fields; // Don't add anything on edit media panel for WP 3.5+ since we have the metabox 
  33.  
  34. $post_id = $post->ID; 
  35. $lang = $this->model->post->get_language( $post_id ); 
  36.  
  37. $dropdown = new PLL_Walker_Dropdown(); 
  38. $fields['language'] = array( 
  39. 'label' => __( 'Language', 'polylang' ),  
  40. 'input' => 'html',  
  41. 'html' => $dropdown->walk( $this->model->get_languages_list(), array( 
  42. 'name' => sprintf( 'attachments[%d][language]', $post_id ),  
  43. 'class' => 'media_lang_choice',  
  44. 'selected' => $lang ? $lang->slug : '',  
  45. ) ),  
  46. ); 
  47.  
  48. return $fields; 
  49.  
  50. /** 
  51. * Creates a media translation 
  52. * @since 1.8 
  53. * @param int $post_id 
  54. * @param string|object $lang 
  55. * @return int id of the translated media 
  56. */ 
  57. public function create_media_translation( $post_id, $lang ) { 
  58. $post = get_post( $post_id ); 
  59.  
  60. if ( empty( $post ) ) { 
  61. return $post; 
  62.  
  63. $lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug 
  64.  
  65. // Create a new attachment ( translate attachment parent if exists ) 
  66. $post->ID = null; // Will force the creation 
  67. $post->post_parent = ( $post->post_parent && $tr_parent = $this->model->post->get_translation( $post->post_parent, $lang->slug ) ) ? $tr_parent : 0; 
  68. $post->tax_input = array( 'language' => array( $lang->slug ) ); // Assigns the language 
  69. $tr_id = wp_insert_attachment( $post ); 
  70.  
  71. // Copy metadata, attached file and alternative text 
  72. foreach ( array( '_wp_attachment_metadata', '_wp_attached_file', '_wp_attachment_image_alt' ) as $key ) { 
  73. if ( $meta = get_post_meta( $post_id, $key , true ) ) { 
  74. add_post_meta( $tr_id, $key, $meta ); 
  75.  
  76. $this->model->post->set_language( $tr_id, $lang ); 
  77.  
  78. $translations = $this->model->post->get_translations( $post_id ); 
  79. if ( ! $translations && $src_lang = $this->model->post->get_language( $post_id ) ) { 
  80. $translations[ $src_lang->slug ] = $post_id; 
  81.  
  82. $translations[ $lang->slug ] = $tr_id; 
  83. $this->model->post->save_translations( $tr_id, $translations ); 
  84.  
  85. /** 
  86. * Fires after a media translation is created 
  87. * @since 1.6.4 
  88. * @param int $post_id post id of the source media 
  89. * @param int $tr_id post id of the new media translation 
  90. * @param string $slug language code of the new translation 
  91. */ 
  92. do_action( 'pll_translate_media', $post_id, $tr_id, $lang->slug ); 
  93. return $tr_id; 
  94.  
  95. /** 
  96. * Creates a media translation 
  97. * @since 0.9 
  98. */ 
  99. public function translate_media() { 
  100. // Security check 
  101. check_admin_referer( 'translate_media' ); 
  102. $post_id = (int) $_GET['from_media']; 
  103.  
  104. // Bails if the translations already exists 
  105. // See https://wordpress.org/support/topic/edit-translation-in-media-attachments?#post-7322303 
  106. // Or if the source media does not exist 
  107. if ( $this->model->post->get_translation( $post_id, $_GET['new_lang'] ) || ! get_post( $post_id ) ) { 
  108. wp_safe_redirect( wp_get_referer() ); 
  109. exit; 
  110.  
  111. $tr_id = $this->create_media_translation( $post_id, $_GET['new_lang'] ); 
  112. wp_safe_redirect( admin_url( sprintf( 'post.php?post=%d&action=edit', $tr_id ) ) ); // WP 3.5+ 
  113. exit; 
  114.  
  115. /** 
  116. * Called when a media is saved 
  117. * Saves language and translations 
  118. * @since 0.9 
  119. * @param array $post 
  120. * @param array $attachment 
  121. * @return array unmodified $post 
  122. */ 
  123. public function save_media( $post, $attachment ) { 
  124. // Language is filled in attachment by the function applying the filter 'attachment_fields_to_save' 
  125. // All security checks have been done by functions applying this filter 
  126. if ( ! empty( $attachment['language'] ) ) { 
  127. $this->model->post->set_language( $post['ID'], $attachment['language'] ); 
  128.  
  129. if ( isset( $_POST['media_tr_lang'] ) ) { 
  130. $this->save_translations( $post['ID'], $_POST['media_tr_lang'] ); 
  131.  
  132. return $post; 
  133.  
  134. /** 
  135. * Prevents WP deleting files when there are still media using them 
  136. * Thanks to Bruno "Aesqe" Babic and its plugin file gallery in which I took all the ideas for this function 
  137. * @since 0.9 
  138. * @param string $file 
  139. * @return string unmodified $file 
  140. */ 
  141. public function wp_delete_file( $file ) { 
  142. global $wpdb; 
  143.  
  144. $uploadpath = wp_upload_dir(); 
  145.  
  146. $ids = $wpdb->get_col( $wpdb->prepare( " 
  147. SELECT post_id FROM $wpdb->postmeta 
  148. WHERE meta_key = '_wp_attached_file' AND meta_value = '%s'",  
  149. substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) ) 
  150. ) ); 
  151.  
  152. if ( ! empty( $ids ) ) { 
  153. // Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before ) 
  154. wp_update_attachment_metadata( $ids[0], wp_generate_attachment_metadata( $ids[0], $file ) ); 
  155. return ''; // Prevent deleting the main file 
  156.  
  157. return $file;