PluginProbe
Advanced Custom Fields (ACF®) / 6.8.1
Advanced Custom Fields (ACF®) v6.8.1
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / wpml.php
wpml.php
326 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package ACF
4 * @author WP Engine
5 *
6 * © 2026 Advanced Custom Fields (ACF®). All rights reserved.
7 * "ACF" is a trademark of WP Engine.
8 * Licensed under the GNU General Public License v2 or later.
9 * https://www.gnu.org/licenses/gpl-2.0.html
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly
14 }
15
16 if ( ! class_exists( 'ACF_WPML_Compatibility' ) ) :
17
18 class ACF_WPML_Compatibility {
19
20 /**
21 * __construct
22 *
23 * Sets up the class functionality.
24 *
25 * @date 23/06/12
26 * @since 3.1.8
27 *
28 * @param void
29 * @return void
30 */
31 function __construct() {
32
33 // global
34 global $sitepress;
35
36 // update settings
37 acf_update_setting( 'default_language', $sitepress->get_default_language() );
38 acf_update_setting( 'current_language', $sitepress->get_current_language() );
39
40 // localize data
41 acf_localize_data(
42 array(
43 'language' => $sitepress->get_current_language(),
44 )
45 );
46
47 // switch lang during AJAX action
48 add_action( 'acf/verify_ajax', array( $this, 'verify_ajax' ) );
49
50 // prevent 'acf-field' from being translated
51 add_filter( 'get_translatable_documents', array( $this, 'get_translatable_documents' ) );
52
53 // check if 'acf-field-group' is translatable
54 if ( $this->is_translatable() ) {
55
56 // actions
57 add_action( 'acf/upgrade_500_field_group', array( $this, 'upgrade_500_field_group' ), 10, 2 );
58 add_action( 'icl_make_duplicate', array( $this, 'icl_make_duplicate' ), 10, 4 );
59
60 // filters
61 add_filter( 'acf/settings/save_json', array( $this, 'settings_save_json' ) );
62 add_filter( 'acf/settings/load_json', array( $this, 'settings_load_json' ) );
63 }
64 }
65
66 /**
67 * is_translatable
68 *
69 * Returns true if the acf-field-group post type is translatable.
70 * Also adds compatibility with ACF4 settings
71 *
72 * @date 10/04/2015
73 * @since 5.2.3
74 *
75 * @param void
76 * @return boolean
77 */
78 function is_translatable() {
79
80 // global
81 global $sitepress;
82
83 // vars
84 $post_types = $sitepress->get_setting( 'custom_posts_sync_option' );
85
86 // return false if no post types
87 if ( ! acf_is_array( $post_types ) ) {
88 return false;
89 }
90
91 // prevent 'acf-field' from being translated
92 if ( ! empty( $post_types['acf-field'] ) ) {
93 $post_types['acf-field'] = 0;
94 $sitepress->set_setting( 'custom_posts_sync_option', $post_types );
95 }
96
97 // when upgrading to version 5, review 'acf' setting
98 // update 'acf-field-group' if 'acf' is translatable, and 'acf-field-group' does not yet exist
99 if ( ! empty( $post_types['acf'] ) && ! isset( $post_types['acf-field-group'] ) ) {
100 $post_types['acf-field-group'] = 1;
101 $sitepress->set_setting( 'custom_posts_sync_option', $post_types );
102 }
103
104 // return true if acf-field-group is translatable
105 if ( ! empty( $post_types['acf-field-group'] ) ) {
106 return true;
107 }
108
109 // return
110 return false;
111 }
112
113 /**
114 * upgrade_500_field_group
115 *
116 * Update the icl_translations table data when creating the field groups.
117 *
118 * @date 10/04/2015
119 * @since 5.2.3
120 *
121 * @param array $field_group The new field group array.
122 * @param object $ofg The old field group WP_Post object.
123 * @return void
124 */
125 function upgrade_500_field_group( $field_group, $ofg ) {
126
127 // global
128 global $wpdb;
129
130 // get translation rows (old acf4 and new acf5)
131 $old_row = $wpdb->get_row(
132 $wpdb->prepare(
133 "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d",
134 'post_acf',
135 $ofg->ID
136 ),
137 ARRAY_A
138 );
139
140 $new_row = $wpdb->get_row(
141 $wpdb->prepare(
142 "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d",
143 'post_acf-field-group',
144 $field_group['ID']
145 ),
146 ARRAY_A
147 );
148
149 // bail early if no rows
150 if ( ! $old_row || ! $new_row ) {
151 return;
152 }
153
154 // create reference of old trid to new trid
155 // trid is a simple int used to find associated objects
156 if ( empty( $this->trid_ref ) ) {
157 $this->trid_ref = array();
158 }
159
160 // update trid
161 if ( isset( $this->trid_ref[ $old_row['trid'] ] ) ) {
162
163 // this field group is a translation of another, update it's trid to match the previously inserted group
164 $new_row['trid'] = $this->trid_ref[ $old_row['trid'] ];
165 } else {
166
167 // this field group is the first of it's translations, update the reference for future groups
168 $this->trid_ref[ $old_row['trid'] ] = $new_row['trid'];
169 }
170
171 // update icl_translations
172 // Row is created by WPML, and much easier to tweak it here due to the very complicated and nonsensical WPML logic
173 $table = "{$wpdb->prefix}icl_translations";
174 $data = array(
175 'trid' => $new_row['trid'],
176 'language_code' => $old_row['language_code'],
177 );
178 $where = array( 'translation_id' => $new_row['translation_id'] );
179 $data_format = array( '%d', '%s' );
180 $where_format = array( '%d' );
181
182 // allow source_language_code to equal NULL
183 if ( $old_row['source_language_code'] ) {
184 $data['source_language_code'] = $old_row['source_language_code'];
185 $data_format[] = '%s';
186 }
187
188 // update wpdb
189 $result = $wpdb->update( $table, $data, $where, $data_format, $where_format );
190 }
191
192 /**
193 * settings_save_json
194 *
195 * Modifies the json path.
196 *
197 * @date 19/05/2014
198 * @since 5.0.0
199 *
200 * @param string $path The json save path.
201 * @return string
202 */
203 function settings_save_json( $path ) {
204
205 // bail early if dir does not exist
206 if ( ! wp_is_writable( $path ) ) {
207 return $path;
208 }
209
210 // ammend
211 $path = untrailingslashit( $path ) . '/' . acf_get_setting( 'current_language' );
212
213 // make dir if does not exist
214 if ( ! file_exists( $path ) ) {
215 mkdir( $path, 0777, true ); //phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir -- Allow legacy mkdir call as this may fire outside admin.
216 }
217
218 // return
219 return $path;
220 }
221
222 /**
223 * settings_load_json
224 *
225 * Modifies the json path.
226 *
227 * @date 19/05/2014
228 * @since 5.0.0
229 *
230 * @param string $path The json save path.
231 * @return string
232 */
233 function settings_load_json( $paths ) {
234
235 // loop
236 if ( $paths ) {
237 foreach ( $paths as $i => $path ) {
238 $paths[ $i ] = untrailingslashit( $path ) . '/' . acf_get_setting( 'current_language' );
239 }
240 }
241
242 // return
243 return $paths;
244 }
245
246 /**
247 * icl_make_duplicate
248 *
249 * description
250 *
251 * @date 26/02/2014
252 * @since 5.0.0
253 *
254 * @param void
255 * @return void
256 */
257 function icl_make_duplicate( $master_post_id, $lang, $postarr, $id ) {
258
259 // bail early if not acf-field-group
260 if ( $postarr['post_type'] != 'acf-field-group' ) {
261 return;
262 }
263
264 // update the lang
265 acf_update_setting( 'current_language', $lang );
266
267 // duplicate field group specifying the $post_id
268 acf_duplicate_field_group( $master_post_id, $id );
269
270 // always translate independately to avoid many many bugs!
271 // - translation post gets a new key (post_name) when origional post is saved
272 // - local json creates new files due to changed key
273 global $iclTranslationManagement;
274 $iclTranslationManagement->reset_duplicate_flag( $id );
275 }
276
277
278 /**
279 * verify_ajax
280 *
281 * Sets the correct language during AJAX requests.
282 *
283 * @type function
284 * @date 7/08/2015
285 * @since 5.2.3
286 *
287 * @param void
288 * @return void
289 */
290 function verify_ajax() {
291
292 // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Verified elsewhere.
293 // set the language for this AJAX request
294 // this will allow get_posts to work as expected (load posts from the correct language)
295 if ( isset( $_REQUEST['lang'] ) ) {
296 global $sitepress;
297 $sitepress->switch_lang( sanitize_text_field( $_REQUEST['lang'] ) );
298 }
299 // phpcs:enable WordPress.Security.NonceVerification.Recommended
300 }
301
302 /**
303 * get_translatable_documents
304 *
305 * Removes 'acf-field' from the available post types for translation.
306 *
307 * @type function
308 * @date 17/8/17
309 * @since 5.6.0
310 *
311 * @param array $icl_post_types The array of post types.
312 * @return array
313 */
314 function get_translatable_documents( $icl_post_types ) {
315
316 // unset
317 unset( $icl_post_types['acf-field'] );
318
319 // return
320 return $icl_post_types;
321 }
322 }
323
324 acf_new_instance( 'ACF_WPML_Compatibility' );
325 endif; // class_exists check
326