PluginProbe
Polylang / 2.0.3
Polylang v2.0.3
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.0.3, at admin/admin-filters-media.php

191 lines 6.0 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 $lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug
78
79 // Create a new attachment ( translate attachment parent if exists )
80 $post->ID = null; // Will force the creation
81 $post->post_parent = ( $post->post_parent && $tr_parent = $this->model->post->get_translation( $post->post_parent, $lang->slug ) ) ? $tr_parent : 0;
82 $post->tax_input = array( 'language' => array( $lang->slug ) ); // Assigns the language
83 $tr_id = wp_insert_attachment( $post );
84
85 // Copy metadata, attached file and alternative text
86 foreach ( array( '_wp_attachment_metadata', '_wp_attached_file', '_wp_attachment_image_alt' ) as $key ) {
87 if ( $meta = get_post_meta( $post_id, $key , true ) ) {
88 add_post_meta( $tr_id, $key, $meta );
89 }
90 }
91
92 $this->model->post->set_language( $tr_id, $lang );
93
94 $translations = $this->model->post->get_translations( $post_id );
95 if ( ! $translations && $src_lang = $this->model->post->get_language( $post_id ) ) {
96 $translations[ $src_lang->slug ] = $post_id;
97 }
98
99 $translations[ $lang->slug ] = $tr_id;
100 $this->model->post->save_translations( $tr_id, $translations );
101
102 /**
103 * Fires after a media translation is created
104 *
105 * @since 1.6.4
106 *
107 * @param int $post_id post id of the source media
108 * @param int $tr_id post id of the new media translation
109 * @param string $slug language code of the new translation
110 */
111 do_action( 'pll_translate_media', $post_id, $tr_id, $lang->slug );
112 return $tr_id;
113 }
114
115 /**
116 * Creates a media translation
117 *
118 * @since 0.9
119 */
120 public function translate_media() {
121 // Security check
122 check_admin_referer( 'translate_media' );
123 $post_id = (int) $_GET['from_media'];
124
125 // Bails if the translations already exists
126 // See https://wordpress.org/support/topic/edit-translation-in-media-attachments?#post-7322303
127 // Or if the source media does not exist
128 if ( $this->model->post->get_translation( $post_id, $_GET['new_lang'] ) || ! get_post( $post_id ) ) {
129 wp_safe_redirect( wp_get_referer() );
130 exit;
131 }
132
133 $tr_id = $this->create_media_translation( $post_id, $_GET['new_lang'] );
134 wp_safe_redirect( admin_url( sprintf( 'post.php?post=%d&action=edit', $tr_id ) ) ); // WP 3.5+
135 exit;
136 }
137
138 /**
139 * Called when a media is saved
140 * Saves language and translations
141 *
142 * @since 0.9
143 *
144 * @param array $post
145 * @param array $attachment
146 * @return array unmodified $post
147 */
148 public function save_media( $post, $attachment ) {
149 // Language is filled in attachment by the function applying the filter 'attachment_fields_to_save'
150 // All security checks have been done by functions applying this filter
151 if ( ! empty( $attachment['language'] ) ) {
152 $this->model->post->set_language( $post['ID'], $attachment['language'] );
153 }
154
155 if ( isset( $_POST['media_tr_lang'] ) ) {
156 $this->save_translations( $post['ID'], $_POST['media_tr_lang'] );
157 }
158
159 return $post;
160 }
161
162 /**
163 * Prevents WP deleting files when there are still media using them
164 * Thanks to Bruno "Aesqe" Babic and its plugin file gallery in which I took all the ideas for this function
165 *
166 * @since 0.9
167 *
168 * @param string $file
169 * @return string unmodified $file
170 */
171 public function wp_delete_file( $file ) {
172 global $wpdb;
173
174 $uploadpath = wp_upload_dir();
175
176 $ids = $wpdb->get_col( $wpdb->prepare( "
177 SELECT post_id FROM $wpdb->postmeta
178 WHERE meta_key = '_wp_attached_file' AND meta_value = '%s'",
179 substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) )
180 ) );
181
182 if ( ! empty( $ids ) ) {
183 // Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before )
184 wp_update_attachment_metadata( $ids[0], wp_generate_attachment_metadata( $ids[0], $file ) );
185 return ''; // Prevent deleting the main file
186 }
187
188 return $file;
189 }
190 }
191