PluginProbe
Polylang / 0.9.3
Polylang v0.9.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 / include / base.php

base.php in Polylang 0.9.3, at include/base.php

293 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // setups basic functions used for admin and frontend
4 abstract class Polylang_Base {
5 protected $options;
6 protected $home;
7 protected $strings = array(); // strings to translate
8 protected $post_types; // post types to filter by language
9 protected $taxonomies; // taxonomies to filter by language
10
11 // used to cache results
12 private $languages_list = array();
13 private $links = array();
14
15 function __construct() {
16 // init options often needed
17 $this->options = get_option('polylang');
18 $this->home = get_option('home');
19
20 add_action('wp_loaded', array(&$this, 'add_post_types_taxonomies')); // must come late to be sure that all post types and taxonomies are registered
21 }
22
23 // init post types and taxonomies to filter by language
24 function add_post_types_taxonomies() {
25 $post_types = array_merge(PLL_MEDIA_SUPPORT ? array('attachment' => 'attachment') : array(), get_post_types(array('show_ui' => true)));
26 $this->post_types = apply_filters('pll_get_post_types', $post_types);
27 $this->taxonomies = apply_filters('pll_get_taxonomies', get_taxonomies(array('show_ui'=>true)));
28 }
29
30 // returns the list of available languages
31 function get_languages_list($args = array()) {
32 // although get_terms is cached, it is efficient to add our own cache
33 if (isset($this->languages_list[$cache_key = md5(serialize($args))]))
34 return $this->languages_list[$cache_key];
35
36 $defaults = array('hide_empty' => false, 'orderby'=> 'term_group');
37 $args = wp_parse_args($args, $defaults);
38 return $this->languages_list[$cache_key] = get_terms('language', $args);
39 }
40
41 // retrieves the dropdown list of the languages
42 function dropdown_languages($args = array()) {
43 $args = apply_filters('pll_dropdown_language_args', $args);
44 $defaults = array('name' => 'lang_choice', 'class' => '', 'add_options' => array(), 'hide_empty' => false, 'value' => 'slug', 'selected' => '');
45 extract(wp_parse_args($args, $defaults));
46
47 // sort $add_options by value
48 uasort($add_options, create_function('$a, $b', "return \$a['value'] > \$b['value'];" ));
49
50 $out = sprintf('<select name="%1$s" id="%1$s"%2$s>'."\n", esc_attr($name), $class ? ' class="'.esc_attr($class).'"' : '');
51 foreach ($add_options as $option)
52 $out .= "<option value='" . $option['value'] . "'>" . $option['text'] . "</option>\n";
53 foreach ($this->get_languages_list($args) as $language) {
54 $out .= sprintf("<option value='%s'%s>%s</option>\n",
55 esc_attr($language->$value),
56 $language->$value == $selected ? ' selected="selected"' : '',
57 esc_html($language->name)
58 );
59 }
60 $out .= "</select>\n";
61 return $out;
62 }
63
64 // returns the language by its id or its slug
65 // Note: it seems that a numeric value is better for performance (3.2.1)
66 function get_language($value) {
67 $lang = is_object($value) ? $value :
68 ((is_numeric($value) || (int) $value) ? get_term((int) $value, 'language') :
69 (is_string($value) ? get_term_by('slug', $value , 'language') : // seems it is not cached in 3.2.1
70 false));
71 return isset($lang) && $lang && !is_wp_error($lang) ? $lang : false;
72 }
73
74 // saves translations for posts or terms
75 // the underscore in '_lang' hides the post meta in the Custom Fields metabox in the Edit Post screen
76 // $type: either 'post' or 'term'
77 // $id: post id or term id
78 // $translations: an associative array of translations with language code as key and translation id as value
79 function save_translations($type, $id, $translations) {
80 $lang = call_user_func(array(&$this, 'get_'.$type.'_language'), $id);
81 if (!$lang)
82 return;
83
84 if (isset($translations) && is_array($translations)) {
85 $translations = array_merge(array($lang->slug => $id), $translations);
86 foreach($translations as $key=>$p)
87 update_metadata($type, (int) $p, '_translations', $translations);
88 }
89 }
90
91 // deletes a translation of a post or term
92 function delete_translation($type, $id) {
93 $translations = $this->get_translations($type, $id);
94 if (is_array($translations)) {
95 $slug = array_search($id, $translations);
96 unset($translations[$slug]);
97 foreach($translations as $p)
98 update_metadata($type, (int) $p, '_translations', $translations);
99 delete_metadata($type, $id, '_translations');
100 }
101 }
102
103 // returns the id of the translation of a post or term
104 // $type: either 'post' or 'term'
105 // $id: post id or term id
106 // $lang: object or slug (in the order of preference latest to avoid)
107 function get_translation($type, $id, $lang) {
108 $translations = $this->get_translations($type, $id);
109 $slug = $this->get_language($lang)->slug;
110 return isset($translations[$slug]) ? (int) $translations[$slug] : false;
111 }
112
113 // returns an array of translations of a post or term
114 function get_translations($type, $id) {
115 // maybe_unserialize due to useless serialization in versions < 0.9
116 return maybe_unserialize(get_metadata($type, $id, '_translations', true));
117 }
118
119 // store the post language in the database
120 function set_post_language($post_id, $lang) {
121 wp_set_post_terms($post_id, $lang ? $this->get_language($lang)->slug : '', 'language' );
122 }
123
124 // returns the language of a post
125 function get_post_language($post_id) {
126 $lang = get_the_terms($post_id, 'language' );
127 return ($lang) ? reset($lang) : false; // there's only one language per post : first element of the array returned
128 }
129
130 // among the post and its translations, returns the id of the post which is in $lang
131 function get_post($post_id, $lang) {
132 $post_lang = $this->get_post_language($post_id);
133 if (!$lang || !$post_lang)
134 return false;
135
136 $lang = $this->get_language($lang);
137 return $post_lang->term_id == $lang->term_id ? $post_id : $this->get_translation('post', $post_id, $lang);
138 }
139
140 // store the term language in the database
141 function set_term_language($term_id, $lang) {
142 update_metadata('term', $term_id, '_language', $lang ? $this->get_language($lang)->term_id : 0);
143 }
144
145 // remove the term language in the database
146 function delete_term_language($term_id) {
147 delete_metadata('term', $term_id, '_language');
148 }
149
150 // returns the language of a term
151 function get_term_language($value, $taxonomy = '') {
152 if (is_numeric($value))
153 $term_id = $value;
154 elseif (is_string($value) && $taxonomy)
155 $term_id = get_term_by('slug', $value , $taxonomy)->term_id;
156 return $term_id ? $this->get_language(get_metadata('term', $term_id, '_language', true)) : false;
157 }
158
159 // among the term and its translations, returns the id of the term which is in $lang
160 function get_term($term_id, $lang) {
161 $lg = $this->get_term_language($term_id);
162 if (!$lang || !$lg)
163 return false;
164
165 $lang = $this->get_language($lang);
166 return $lg->term_id == $lang->term_id ? $term_id : $this->get_translation('term', $term_id, $lang);
167 }
168
169 // adds language information to a link when using pretty permalinks
170 function add_language_to_link($url, $lang) {
171 if (!isset($lang) || !$lang)
172 return $url;
173
174 global $wp_rewrite;
175 if ($wp_rewrite->using_permalinks()) {
176 $base = $this->options['rewrite'] ? '' : 'language/';
177 $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base.$lang->slug.'/';
178 return esc_url(str_replace($this->home.'/'.$wp_rewrite->root, $this->home.'/'.$wp_rewrite->root.$slug, $url));
179 }
180
181 // special case for pages which do not accept adding the lang parameter
182 elseif ('_get_page_link' != current_filter())
183 return add_query_arg( 'lang', $lang->slug, $url );
184
185 return $url;
186 }
187
188 // optionally rewrite posts, pages links to filter them by language
189 // rewrite post format (and optionally categories and post tags) archives links to filter them by language
190 function add_post_term_link_filters() {
191 if ($this->options['force_lang'] && $GLOBALS['wp_rewrite']->using_permalinks()) {
192 foreach (array('post_link', '_get_page_link', 'post_type_link') as $filter)
193 add_filter($filter, array(&$this, 'post_link'), 10, 2);
194 }
195
196 add_filter('term_link', array(&$this, 'term_link'), 10, 3);
197 }
198
199 // modifies post & page links
200 function post_link($link, $post) {
201 if (isset($this->links[$link]))
202 return $this->links[$link];
203
204 return $this->links[$link] = ('post_type_link' == current_filter() && !in_array($post->post_type, $this->post_types)) ?
205 $link : $this->add_language_to_link($link, $this->get_post_language('_get_page_link' == current_filter() ? $post : $post->ID));
206 }
207
208 // modifies term link
209 function term_link($link, $term, $tax) {
210 if (isset($this->links[$link]))
211 return $this->links[$link];
212
213 $ok = $tax == 'post_format' || ($this->options['force_lang'] && $GLOBALS['wp_rewrite']->using_permalinks() && in_array($tax, $this->taxonomies));
214 return $this->links[$link] = $ok ? $this->add_language_to_link($link, $this->get_term_language($term->term_id)) : $link;
215 }
216
217 // returns the html link to the flag if exists
218 // $lang: object
219 function get_flag($lang) {
220 if (file_exists(POLYLANG_DIR.($file = '/flags/'.$lang->description.'.png')))
221 $url = POLYLANG_URL.$file;
222
223 // overwrite with custom flags
224 if (!is_admin() && ( // never use custom flags on admin side
225 file_exists(PLL_LOCAL_DIR.($file = '/'.$lang->description.'.png')) ||
226 file_exists(PLL_LOCAL_DIR.($file = '/'.$lang->description.'.jpg')) ))
227 $url = PLL_LOCAL_URL.$file;
228
229 $title = apply_filters('pll_flag_title', $lang->name, $lang->slug, $lang->description);
230 return isset($url) ? '<img src="'.esc_url($url).'" title="'.esc_attr($title).'" alt="'.esc_attr($lang->name).'" />' : '';
231 }
232
233 // adds clauses to comments query - used in both frontend and admin
234 function _comments_clauses($clauses, $lang) {
235 global $wpdb;
236
237 // if this clause is not already added by WP
238 if (!strpos($clauses['join'], '.ID'))
239 $clauses['join'] .= " JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
240
241 $clauses['join'] .= " INNER JOIN $wpdb->term_relationships AS pll_tr ON pll_tr.object_id = ID";
242 $clauses['where'] .= $wpdb->prepare(" AND pll_tr.term_taxonomy_id = %d", $lang->term_taxonomy_id);
243
244 return $clauses;
245 }
246
247 // adds terms clauses to get_terms - used in both frontend and admin
248 function _terms_clauses($clauses, $lang) {
249 global $wpdb;
250 if (isset($lang) && $lang) {
251 $clauses['join'] .= $wpdb->prepare(" LEFT JOIN $wpdb->termmeta AS pll_tm ON t.term_id = pll_tm.term_id");
252 $clauses['where'] .= $wpdb->prepare(" AND pll_tm.meta_key = '_language' AND pll_tm.meta_value IN ($lang->term_id)");
253 }
254 return $clauses;
255 }
256
257 // returns all page ids *not in* language defined by $lang_id
258 function exclude_pages($lang_id) {
259 $q = array(
260 'numberposts' => -1,
261 'post_type' => array_intersect(get_post_types(array('hierarchical' => 1)), $this->post_types),
262 'fields' => 'ids',
263 'tax_query' => array(array(
264 'taxonomy' => 'language',
265 'fields' => 'id',
266 'terms' => $lang_id,
267 'operator' => 'NOT IN'
268 ))
269 );
270 return get_posts($q);
271 }
272
273 // export a mo object in options
274 function mo_export($mo, $lang) {
275 $strings = array();
276 foreach ($mo->entries as $entry)
277 $strings[] = array($entry->singular, $mo->translate($entry->singular));
278 update_option('polylang_mo'.$lang->term_id, $strings);
279 }
280
281 // import a mo object from options
282 function mo_import($lang) {
283 $mo = new MO();
284 if ($strings = get_option('polylang_mo'.$lang->term_id)) {
285 foreach ($strings as $msg)
286 $mo->add_entry($mo->make_entry($msg[0], $msg[1]));
287 }
288 return $mo;
289 }
290
291 } //class Polylang_Base
292 ?>
293