PluginProbe ʕ •ᴥ•ʔ
Nested Pages / 3.2.15
Nested Pages v3.2.15
3.2.15 3.2.14 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 trunk 1.0 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.3.0 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.2 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.3.1 1.6.3.2 1.6.4 1.6.5 1.6.5.1 1.6.5.2 1.6.6 1.6.7 1.6.8 1.7.0 1.7.1 2.0.1 2.0.2 2.0.3 2.0.4 3.0.1 3.0.10 3.0.11 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.20 3.1.21 3.1.22 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7
wp-nested-pages / app / Entities / PluginIntegration / WPML.php
wp-nested-pages / app / Entities / PluginIntegration Last commit date
AdvancedCustomFields.php 8 years ago DarkMode.php 7 years ago EditorialAccessManager.php 8 years ago IntegrationFactory.php 7 years ago WPML.php 3 years ago YoastSeo.php 3 years ago
WPML.php
348 lines
1 <?php
2 namespace NestedPages\Entities\PluginIntegration;
3
4 use NestedPages\Entities\Post\PostRepository;
5
6 /**
7 * WPML Integration
8 * @link https://wpml.org/
9 */
10 class WPML
11 {
12 /**
13 * Installed
14 * @var boolean
15 */
16 public $installed = false;
17
18 /**
19 * Global Sitepress object
20 */
21 private $sitepress;
22
23 /**
24 * WPML Settings
25 */
26 private $settings;
27
28 /**
29 * Post Repository
30 */
31 private $post_repo;
32
33 public function __construct()
34 {
35 if ( defined('ICL_SITEPRESS_VERSION') ){
36 $this->installed = true;
37 global $sitepress;
38 $this->sitepress = $sitepress;
39 $this->settings = get_option('icl_sitepress_settings');
40 $this->post_repo = new PostRepository;
41 return;
42 }
43 }
44
45 /**
46 * Get the current language
47 * @return string
48 */
49 public function getCurrentLanguage($return_type = 'code')
50 {
51 if ( $return_type == 'code' ) return ICL_LANGUAGE_CODE;
52 if ( $return_type == 'name' ) return ICL_LANGUAGE_NAME;
53 if ( $return_type == 'name_en' ) return ICL_LANGUAGE_NAME_EN;
54 }
55
56 /**
57 * Get all available languages
58 * @return array
59 */
60 public function getLanguages()
61 {
62 return icl_get_languages();
63 }
64
65 /**
66 * Get the default language
67 * @return array
68 */
69 public function getDefaultLanguage()
70 {
71 return $this->sitepress->get_default_language();
72 }
73
74 /**
75 * Get a single language
76 * @return array
77 */
78 public function getSingleLanguage($language = 'en')
79 {
80 $languages = $this->getLanguages();
81 return ( array_key_exists($language, $languages) ) ? $languages[$language] : [];
82 }
83
84 /**
85 * Is the default language currently being shown
86 * @return boolean
87 */
88 public function isDefaultLanguage()
89 {
90 return ( $this->getCurrentLanguage() == $this->getDefaultLanguage() ) ? true : false;
91 }
92
93 /**
94 * Get all translations for a post
95 * @return array or int
96 */
97 public function getAllTranslations($post_id, $return = 'array')
98 {
99 if ( !$post_id && $return == 'array' ) return [];
100 if ( !$post_id && $return == 'count' ) return 0;
101 $true_id = $this->sitepress->get_element_trid($post_id);
102 if ( $return == 'array' ) return $this->sitepress->get_element_translations($true_id);
103 if ( $return == 'count' ) return count($this->sitepress->get_element_translations($true_id));
104 }
105
106 /**
107 * Get the primary language post ID for a provided child id
108 * @param int
109 * @return int - post id
110 */
111 public function getPrimaryLanguagePost($post_id)
112 {
113 $all_translations = $this->getAllTranslations($post_id);
114 foreach ( $all_translations as $translation ){
115 if ( $translation->language_code == $this->getDefaultLanguage() ) return $translation->element_id;
116 }
117 }
118
119 /**
120 * Sync Post Order among translations
121 * @param array of posts with children
122 * @param int value of the parent ID
123 */
124 public function syncPostOrder($posts, $post_parent = 0)
125 {
126 if ( $this->settings['sync_page_ordering'] !== 1 ) return;
127 global $wpdb;
128 if ( !is_array($posts) ) return;
129 foreach ( $posts as $order => $post ) :
130 $translations = $this->getAllTranslations($post['id']);
131 foreach ( $translations as $lang_code => $post_info ) :
132 $translation_post_id = $post_info->element_id;
133 $parent_translations = $this->getAllTranslations($post_parent);
134 $translated_parent = ( isset($parent_translations[$lang_code]) ) ? $parent_translations[$lang_code]->element_id : 0;
135 $query = "UPDATE $wpdb->posts SET menu_order = '$order', post_parent = '$translated_parent' WHERE ID = '$translation_post_id'";
136 $wpdb->query( $query );
137 endforeach;
138 if (isset($post['children'])) :
139 $this->syncPostOrder($post['children'], $post['id']);
140 endif;
141 endforeach;
142 }
143
144 /**
145 * Output the sync menus button
146 * @return html
147 */
148 public function syncMenusButton()
149 {
150 $url = esc_url(admin_url('admin.php?page=sitepress-multilingual-cms/menu/menu-sync/menus-sync.php'));
151 return '<a href="' . $url . '" class="np-btn">' . __('Sync WPML Menus', 'wp-nested-pages') . '</a>';
152 }
153
154 /**
155 * Get the Translated IDs of an array of post IDs
156 * @param array $post_ids
157 * @return array of post ids
158 */
159 public function getAllTranslatedIds($post_ids)
160 {
161 if ( !is_array($post_ids) ) return [];
162 foreach ( $post_ids as $id ){
163 $translations = $this->getAllTranslations($id);
164 if ( empty($translations) ) continue;
165 foreach ( $translations as $lang => $post ){
166 if ( $post->element_id == $id ) continue;
167 array_push($post_ids, $post->element_id);
168 }
169 }
170 return $post_ids;
171 }
172
173 /**
174 * Get the number of translated posts for a post type
175 */
176 public function translatedPostCount($language_code = '', $post_type = '')
177 {
178 global $wpdb;
179 $post_type = 'post_' . $post_type;
180 $query = $wpdb->prepare("SELECT COUNT( {$wpdb->prefix}posts.ID ) FROM {$wpdb->prefix}posts LEFT JOIN {$wpdb->prefix}icl_translations ON {$wpdb->prefix}posts.ID = {$wpdb->prefix}icl_translations.element_id WHERE {$wpdb->prefix}icl_translations.language_code = '%s' AND {$wpdb->prefix}icl_translations.element_type = '%s'", $language_code, $post_type);
181
182 return $wpdb->get_var( $query );
183 }
184
185 /**
186 * Get the number of default language posts for a post type
187 */
188 public function defaultPostCount($post_type = '')
189 {
190 global $wpdb;
191 $default_language_code = $this->getDefaultLanguage();
192 $query = $wpdb->prepare("SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->prefix}posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS t ON t.element_id = p.ID AND t.element_type = CONCAT('post_', p.post_type) WHERE p.post_type = '%s' AND t.language_code = '%s' AND p.post_status != 'draft'", $post_type, $default_language_code);
193 return $wpdb->get_var( $query );
194 }
195
196 /**
197 * Output a list of language links in the tools section of the listing head
198 * @param string $post_type
199 * @return string html
200 * @example English (2) | German (1) | Spanish (0)
201 */
202 public function languageToolLinks($post_type)
203 {
204 $html = '<ul class="subsubsub" style="clear:both;">';
205 $c = 1;
206 $languages = $this->getLanguages();
207 foreach ( $languages as $lang_code => $lang ){
208 $translated_language = $this->getTranslatedLanguageName($this->getDefaultLanguage(), $lang_code);
209 if ( !$translated_language ) continue;
210 $post_count = ( $lang_code == $this->getDefaultLanguage() )
211 ? $this->defaultPostCount($post_type)
212 : $this->translatedPostCount($lang_code, $post_type);
213 $html .= '<li>';
214 if ( $c > 1 ) $html .= '|&nbsp;';
215 if ( $lang['active'] ) $html .= '<strong>';
216 if ( $post_count > 0 ) $html .= '<a href="' . $this->getLanguageFilteredLink($lang_code, $post_type) . '">';
217 $html .= $translated_language . ' ';
218 if ( $lang_code !== $this->getDefaultLanguage() ) $html .= '(' . $post_count . ')';
219 if ( $lang_code == $this->getDefaultLanguage() ) $html .= '(' . $post_count . ')';
220 if ( $lang['active'] ) $html .= '</strong>';
221 if ( $post_count > 0 ) $html .= '</a>';
222 $html .= '&nbsp;</li>';
223 $c++;
224 }
225 $html .= '<li>|&nbsp;<a href="' . $this->getLanguageFilteredLink('all', $post_type) . '">' . __('All Languages', 'wp-nested-pages') . '</a></li>';
226 $html .= '</ul>';
227 return $html;
228 }
229
230 /**
231 * Get the Links to a filtered language
232 */
233 public function getLanguageFilteredLink($language, $post_type)
234 {
235 $url = 'admin.php?page=nestedpages';
236 if ( $post_type !== 'page' ) $url .= '-' . $post_type;
237 $url .= '&lang=' . $language;
238 return esc_url(admin_url($url));
239 }
240
241 /**
242 * Get a translated language name for a given language
243 * @param string $translated_language - the language to return as
244 * @param string $target_language - the language to translate
245 * @return string - translated name of language (ex: if default is english, and target is spanish, will return "Spanish" rather than "Espanol")
246 */
247 public function getTranslatedLanguageName($translated_language, $target_language)
248 {
249 global $wpdb;
250 $query = $wpdb->prepare("SELECT * FROM {$wpdb->prefix}icl_languages_translations WHERE language_code = '%s' AND display_language_code = '%s'", $target_language, $translated_language);
251 $results = $wpdb->get_results( $query );
252 return ( $results[0]->name ) ? $results[0]->name : null;
253 }
254
255 /**
256 * Sync fields across all langauges
257 */
258 public function syncPosts($post_id)
259 {
260 $all_translations = $this->getAllTranslations($post_id);
261 $source_template = get_post_meta($post_id, '_wp_page_template', true);
262 $source_post = get_post($post_id);
263 $sticky_flag = ( $this->settings['sync_sticky_flag'] ) ? get_option('sticky_posts') : [];
264 foreach ( $all_translations as $translation ) :
265 if ( $translation->element_id == $post_id ) continue;
266 if ( $this->settings['sync_page_template'] && $source_template ){
267 update_post_meta(
268 $translation->element_id,
269 '_wp_page_template',
270 $source_template
271 );
272 }
273 $update_args = [];
274 if ( $this->settings['sync_comment_status'] ) $update_args['comment_status'] = $source_post->comment_status;
275 if ( $this->settings['sync_post_date'] ) $update_args['post_date'] = $source_post->post_date;
276 if ( $this->settings['sync_post_date'] ) $update_args['post_date_gmt'] = $source_post->post_date_gmt;
277 if ( $this->settings['sync_ping_status'] ) $update_args['post_status'] = $source_post->post_status;
278 if ( $this->settings['sync_password'] ) $update_args['post_password'] = $source_post->post_password;
279 if ( $this->settings['sync_private_flag'] ) $update_args['post_status'] = $source_post->post_status;
280 if ( $this->settings['sync_post_taxonomies'] ) $this->syncTaxonomies($post_id);
281 endforeach;
282 }
283
284 /**
285 * Sync Taxonomies across all languages
286 */
287 public function syncTaxonomies($source_post_id)
288 {
289 global $wpdb;
290 $all_translations = $this->getAllTranslations($source_post_id);
291 $terms = $this->post_repo->getAllTerms($source_post_id);
292 $translated_terms = [];
293
294 // Get all translations for the terms
295 foreach ( $terms as $term ){
296 if ( $term->tax_name == 'language' ) continue;
297 $query = "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id = $term->term_id AND element_type LIKE 'tax_%'";
298 $trid = $wpdb->get_var($query);
299 if ( !$trid ) continue;
300 $translated_terms[] = $this->getTermTranslations($trid);
301 if ( !$translated_terms ) continue;
302 }
303
304 foreach ( $all_translations as $translation ) :
305 if ( $translation->element_id == $source_post_id ) continue;
306 if ( !$terms ) continue;
307
308 // Build the array of terms to sync
309 foreach ( $translated_terms as $term_translations ) :
310 foreach ( $term_translations as $trans ) :
311 $taxonomy = get_taxonomy($trans->taxonomy);
312 $tax_hierarchical = $taxonomy->hierarchical;
313 if ( $trans->language_code == $translation->language_code ) {
314 $translation->terms[$trans->taxonomy][] = ($tax_hierarchical) ? $trans->term_id : $trans->name;
315 }
316 endforeach;
317 endforeach;
318
319 if ( !is_array($translation->terms) ) continue;
320 foreach ( $translation->terms as $taxonomy => $terms ) :
321 wp_set_post_terms($translation->element_id, $terms, $taxonomy, false);
322 endforeach;
323 endforeach;
324 }
325
326 /**
327 * Get all the translations for a term
328 */
329 public function getTermTranslations($trid)
330 {
331 global $wpdb;
332 return $wpdb->get_results($wpdb->prepare("SELECT iclt.language_code, t.term_id, t.name, t.slug, tt.taxonomy FROM {$wpdb->prefix}icl_translations AS iclt LEFT JOIN {$wpdb->prefix}terms AS t ON t.term_id = iclt.element_id LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt ON tt.term_id = t.term_id WHERE trid = %s", $trid));
333 }
334
335 /**
336 * Get the count of published posts for a post type in a specific language
337 * @param $post_type string – post type name
338 * @param $language string - language code
339 */
340 public function getPostTypeCountByLanguage($post_type, $language = null)
341 {
342 if ( !$language ) $language = $this->getCurrentLanguage();
343 global $wpdb;
344 $query = $wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS trans ON p.ID = trans.element_id WHERE post_type = %s AND p.post_status = 'publish' AND trans.language_code = %s", $post_type, $language);
345 return $wpdb->get_var($query);
346 }
347 }
348