PluginProbe
Polylang / 2.3.6
Polylang v2.3.6
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / admin / admin-filters-media.php

admin-filters-media.php in Polylang 2.3.6, at admin/admin-filters-media.php

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