PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / trunk
Pods – Custom Content Types and Fields vtrunk
trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / src / Pods / Integrations / Polylang.php
pods / src / Pods / Integrations Last commit date
Query_Monitor 4 months ago WPGraphQL 4 months ago Enfold.php 4 months ago Genesis.php 4 months ago Jetpack.php 4 months ago Polylang.php 4 months ago Query_Monitor.php 4 months ago Service_Provider.php 4 months ago WPML.php 4 months ago YARPP.php 4 months ago
Polylang.php
476 lines
1 <?php
2
3 namespace Pods\Integrations;
4
5 // Don't load directly.
6 if ( ! defined( 'ABSPATH' ) ) {
7 die( '-1' );
8 }
9
10 use Pods\Integration;
11
12 /**
13 * Class Polylang
14 *
15 * @since 2.8.0
16 */
17 class Polylang extends Integration {
18
19 protected $hooks = [
20 'action' => [
21 'pods_meta_init' => [ 'pods_meta_init' ],
22 'pods_form_ui_field_pick_related_objects_other' => [ 'pods_pick_field_add_related_objects' ],
23 ],
24 'filter' => [
25 'pods_get_current_language' => [ 'pods_get_current_language', 10, 2 ],
26 'pods_api_get_table_info' => [ 'pods_api_get_table_info', 10, 7 ],
27 'pods_data_traverse_recurse_ignore_aliases' => [ 'pods_data_traverse_recurse_ignore_aliases', 10 ],
28 'pods_meta_ignored_types' => [ 'pods_meta_ignored_types' ],
29 'pods_component_i18n_admin_data' => [ 'pods_component_i18n_admin_data' ],
30 'pods_component_i18n_admin_ui_fields' => [ 'pods_component_i18n_admin_ui_fields', 10, 2 ],
31 'pods_var_post_id' => [ 'pods_var_post_id' ],
32 'pll_get_post_types' => [ 'pll_get_post_types', 10, 2 ],
33 ],
34 ];
35
36 public static function is_active() {
37 return function_exists( 'PLL' ) || ! empty( $GLOBALS['polylang'] );
38 }
39
40 /**
41 * @since 2.8.2
42 *
43 * @param int $id
44 *
45 * @return mixed|void
46 */
47 public function pods_var_post_id( $id ) {
48 $polylang_id = pll_get_post( $id );
49 if ( ! empty( $polylang_id ) ) {
50 $id = $polylang_id;
51 }
52 return $id;
53 }
54
55 /**
56 * Add Pods templates to possible i18n enabled post-types (polylang settings).
57 *
58 * @since 2.7.0
59 * @since 2.8.0 Moved from PodsI18n class.
60 *
61 * @param array $post_types
62 * @param bool $is_settings
63 *
64 * @return array mixed
65 */
66 public function pll_get_post_types( $post_types, $is_settings = false ) {
67
68 if ( $is_settings ) {
69 $post_types['_pods_template'] = '_pods_template';
70 }
71
72 return $post_types;
73 }
74
75 /**
76 * @since 2.8.0
77 *
78 * @param \PodsMeta $pods_meta
79 */
80 public function pods_meta_init( $pods_meta ) {
81
82 if ( function_exists( 'pll_current_language' ) ) {
83 add_action( 'init', array( $pods_meta, 'cache_pods' ), 101, 0 );
84 }
85 }
86
87 /**
88 * @since 2.8.8
89 *
90 * @param array[] $ignored_types
91 *
92 * @return mixed
93 */
94 public function pods_meta_ignored_types( $ignored_types ) {
95
96 // Add Polylang related taxonomies to the ignored types for PodsMeta.
97 $ignored_types['taxonomy']['language'] = true;
98 $ignored_types['taxonomy']['term_language'] = true;
99 $ignored_types['taxonomy']['post_translations'] = true;
100 $ignored_types['taxonomy']['term_translations'] = true;
101
102 return $ignored_types;
103 }
104
105 /**
106 * Add the Polylang language taxonomy to be used in relationships.
107 *
108 * @since 2.8.21
109 */
110 public function pods_pick_field_add_related_objects() {
111 $taxonomy = get_taxonomy( 'language' );
112
113 \PodsField_Pick::$related_objects[ 'taxonomy-language' ] = array(
114 'label' => $taxonomy->label . ' (' . $taxonomy->name . ')',
115 'group' => __( 'Polylang', 'pods' ),
116 'bidirectional' => false,
117 );
118 }
119
120 /**
121 * @since 2.8.0
122 *
123 * @param array $ignore_aliases
124 *
125 * @return array
126 */
127 public function pods_data_traverse_recurse_ignore_aliases( $ignore_aliases ) {
128
129 $ignore_aliases[] = 'polylang_languages';
130
131 return $ignore_aliases;
132 }
133
134 /**
135 * Get the current language.
136 *
137 * @since 2.8.0
138 *
139 * @param string $current_language
140 * @param array $context
141 *
142 * @return string
143 */
144 public function pods_get_current_language( $current_language, $context ) {
145
146 if ( ! is_admin() ) {
147 // Get the global current language (if set).
148 return pll_current_language( 'slug' );
149 }
150
151 $defaults = [
152 'is_admin' => is_admin(),
153 'is_ajax' => null,
154 'is_pods_ajax' => null,
155 'current_page' => '',
156 'current_object_type' => '',
157 'current_item_id' => '',
158 'current_item_type' => '',
159 ];
160
161 $context = wp_parse_args( $context, $defaults );
162
163 $object_type = $context['current_object_type'];
164 $item_id = $context['current_item_id'];
165 $item_type = $context['current_item_type'];
166
167 /**
168 * Get the current user's preferred language.
169 * This is a user meta setting that will overwrite the language returned from pll_current_language().
170 *
171 * @see \PLL_Admin_Base::init_user() (polylang/admin/admin-base.php)
172 */
173 $current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
174
175 if ( ! $item_type ) {
176 return $current_language;
177 }
178
179 /**
180 * In polylang the preferred language could be anything.
181 */
182 switch ( $object_type ) {
183 case 'post':
184 if ( $this->is_translated_post_type( $item_type ) ) {
185
186 /**
187 * Polylang (1.5.4+).
188 * We only want the related objects if they are not translatable OR the same language as the current object.
189 */
190 if ( $item_id && function_exists( 'pll_get_post_language' ) ) {
191 // Overwrite the current language if this is a translatable post_type.
192 $current_language = pll_get_post_language( $item_id );
193 }
194
195 /**
196 * Polylang (1.0.1+).
197 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language.
198 */
199 $current_language = pods_v( 'new_lang', 'request', $current_language );
200 }
201 break;
202
203 case 'term':
204 if ( $this->is_translated_taxonomy( $item_type ) ) {
205
206 /**
207 * Polylang (1.5.4+).
208 * We only want the related objects if they are not translatable OR the same language as the current object.
209 */
210 if ( $item_id && function_exists( 'pll_get_term_language' ) ) {
211 // Overwrite the current language if this is a translatable taxonomy
212 $current_language = pll_get_term_language( $item_id );
213 }
214
215 /**
216 * Polylang (1.0.1+).
217 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language.
218 */
219 $current_language = pods_v( 'new_lang', 'request', $current_language );
220 }
221 break;
222 }
223
224 return $current_language;
225 }
226
227 /**
228 * Filter table info data.
229 *
230 * @since 2.8.0
231 *
232 * @param array $info
233 * @param string $object_type
234 * @param string $object
235 * @param string $name
236 * @param array|\Pods $pod
237 * @param array $field
238 * @param \PodsAPI $pods_api
239 *
240 * @return array
241 */
242 public function pods_api_get_table_info( $info, $object_type, $object, $name, $pod, $field, $pods_api ) {
243 global $wpdb;
244 $object_name = pods_sanitize( ( empty( $object ) ? $name : $object ) );
245
246 // Get current language data
247 $lang_data = $this->get_language_data();
248
249 if ( ! $lang_data ) {
250 return $info;
251 }
252
253 $current_language_tt_id = 0;
254 $current_language_tl_tt_id = 0;
255
256 if ( ! empty( $lang_data['tt_id'] ) ) {
257 $current_language_tt_id = $lang_data['tt_id'];
258 }
259 if ( ! empty( $lang_data['tl_tt_id'] ) ) {
260 $current_language_tl_tt_id = $lang_data['tl_tt_id'];
261 }
262
263 switch ( $object_type ) {
264
265 case 'post':
266 case 'post_type':
267 case 'media':
268 if ( $current_language_tt_id && $this->is_translated_post_type( $object_name ) ) {
269 $info['join']['polylang_languages'] = "
270 LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
271 ON `polylang_languages`.`object_id` = `t`.`ID`
272 AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
273 ";
274
275 $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL";
276 }
277 break;
278
279 case 'taxonomy':
280 case 'term':
281 case 'nav_menu':
282 case 'post_format':
283 if ( $current_language_tl_tt_id && $this->is_translated_taxonomy( $object_name ) ) {
284 $info['join']['polylang_languages'] = "
285 LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
286 ON `polylang_languages`.`object_id` = `t`.`term_id`
287 AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id}
288 ";
289
290 $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL";
291 }
292 break;
293 }
294
295 return $info;
296 }
297
298 /**
299 * @param array $data
300 *
301 * @return array
302 */
303 public function pods_component_i18n_admin_data( $data ) {
304
305 foreach ( $data as $lang => $field_data ) {
306 if ( in_array( $lang, $this->get_locales(), true ) ) {
307 $data[ $lang ]['polylang'] = true;
308 } else {
309 $data[ $lang ]['polylang'] = false;
310 }
311 }
312
313 return $data;
314 }
315
316 /**
317 * @param array $fields
318 * @param array $data
319 *
320 * @return array
321 */
322 public function pods_component_i18n_admin_ui_fields( $fields, $data ) {
323
324 $fields['manage']['polylang'] = array(
325 'label' => __( 'Polylang', 'pods' ),
326 'type' => 'boolean',
327 );
328
329 return $fields;
330 }
331
332 /**
333 * Helper method for backwards compatibility.
334 *
335 * @since 2.8.0
336 *
337 * @param string $object_name
338 *
339 * @return false|mixed|void
340 */
341 public function is_translated_post_type( $object_name ) {
342 if ( function_exists( 'pll_is_translated_post_type' ) ) {
343 return pll_is_translated_post_type( $object_name );
344 }
345 return false;
346 }
347
348 /**
349 * Helper method for backwards compatibility.
350 *
351 * @since 2.8.0
352 *
353 * @param string $object_name
354 *
355 * @return false|mixed|void
356 */
357 public function is_translated_taxonomy( $object_name ) {
358 if ( function_exists( 'pll_is_translated_taxonomy' ) ) {
359 return pll_is_translated_taxonomy( $object_name );
360 }
361 return false;
362 }
363
364 /**
365 * Get the language taxonomy object for the current language.
366 *
367 * @since 2.8.0
368 *
369 * @param string $locale
370 *
371 * @return array
372 */
373 public function get_language_data( $locale = null ) {
374 static $lang_data = [];
375
376 if ( ! $locale ) {
377 $locale = pods_i18n()->get_current_language();
378 }
379
380 if ( isset( $lang_data[ $locale ] ) ) {
381 return $lang_data[ $locale ];
382 }
383
384 if ( ! $locale ) {
385 return null;
386 }
387
388 // We need to return language data
389 $lang_data = array(
390 'language' => $locale,
391 't_id' => 0,
392 'tt_id' => 0,
393 'tl_t_id' => 0,
394 'tl_tt_id' => 0,
395 'term' => null,
396 );
397
398 $language = $this->get_language( $locale );
399
400 // If the language object exists, add it!
401 if ( $language && ! empty( $language->term_id ) ) {
402
403 $lang_data['term'] = $language;
404 $lang_data['t_id'] = (int) $language->term_id;
405
406 if ( method_exists( $language, 'get_tax_prop' ) ) {
407 // Since Polylang 3.4
408 $lang_data['tt_id'] = (int) $language->get_tax_prop( 'language', 'term_taxonomy_id' );
409 $lang_data['tl_t_id'] = (int) $language->get_tax_prop( 'term_language', 'term_id' );
410 $lang_data['tl_tt_id'] = (int) $language->get_tax_prop( 'term_language', 'term_taxonomy_id' );
411 } else {
412 // Pre Polylang 3.4
413 $lang_data['tt_id'] = (int) $language->term_taxonomy_id;
414 $lang_data['tl_t_id'] = (int) $language->tl_term_id;
415 $lang_data['tl_tt_id'] = (int) $language->tl_term_taxonomy_id;
416 }
417 }
418
419 $lang_data[ $locale ] = $lang_data;
420
421 return $lang_data[ $locale ];
422 }
423
424 /**
425 * @param $locale
426 *
427 * @return false|\PLL_Language
428 */
429 public function get_language( $locale ) {
430 $language = false;
431
432 if ( ! $locale ) {
433 $locale = pods_i18n()->get_current_language();
434 }
435
436 // Get the language term object.
437 if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
438 // Polylang 1.8 and newer.
439 $language = PLL()->model->get_language( $locale );
440 } else {
441 global $polylang;
442 if ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
443 // Polylang 1.2 - 1.7.x
444 $language = $polylang->model->get_language( $locale );
445 } elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
446 // Polylang 1.1.x and older.
447 $language = $polylang->get_language( $locale );
448 }
449 }
450
451 return $language;
452 }
453
454 /**
455 * @return string[]
456 */
457 public function get_locales() {
458 $locales = [];
459 if ( function_exists( 'pll_languages_list' ) ) {
460 $locales = pll_languages_list( array( 'fields' => 'locale' ) );
461 }
462 return $locales;
463 }
464
465 /**
466 * @return array
467 */
468 public function get_languages() {
469 $languages = [];
470 if ( function_exists( 'pll_languages_list' ) ) {
471 $languages = pll_languages_list( array( 'fields' => null ) );
472 }
473 return $languages;
474 }
475 }
476