PluginProbe
Polylang / 0.8.3
Polylang v0.8.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.8.3, at include/base.php

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