| 1 |
<?php |
| 2 |
|
| 3 |
/* |
| 4 |
* manages compatibility with 3rd party plugins (and themes) |
| 5 |
* this class is available as soon as the plugin is loaded |
| 6 |
* |
| 7 |
* @since 1.0 |
| 8 |
*/ |
| 9 |
class PLL_Plugins_Compat { |
| 10 |
static protected $instance; // for singleton |
| 11 |
|
| 12 |
/* |
| 13 |
* constructor |
| 14 |
* |
| 15 |
* @since 1.0 |
| 16 |
*/ |
| 17 |
protected function __construct() { |
| 18 |
// WordPress Importer |
| 19 |
add_action('init', array(&$this, 'maybe_wordpress_importer')); |
| 20 |
|
| 21 |
// YARPP |
| 22 |
// just makes YARPP aware of the language taxonomy (after Polylang registered it) |
| 23 |
add_action('init', create_function('',"\$GLOBALS['wp_taxonomies']['language']->yarpp_support = 1;"), 20); |
| 24 |
|
| 25 |
// WordPress SEO by Yoast |
| 26 |
add_action('pll_language_defined', array(&$this, 'wpseo_init')); |
| 27 |
|
| 28 |
// Custom field template |
| 29 |
add_action('add_meta_boxes', array(&$this, 'cft_copy'), 10, 2); |
| 30 |
|
| 31 |
// Aqua Resizer |
| 32 |
add_filter('pll_home_url_black_list', create_function('$arr', "return array_merge(\$arr, array(array('function' => 'aq_resize')));")); |
| 33 |
|
| 34 |
// Twenty Fourteen |
| 35 |
add_filter('transient_featured_content_ids', array(&$this, 'twenty_fourteen_featured_content_ids')); |
| 36 |
add_filter('option_featured-content', array(&$this, 'twenty_fourteen_option_featured_content')); |
| 37 |
|
| 38 |
// Jetpack 3 |
| 39 |
add_action('jetpack_widget_get_top_posts', array(&$this, 'jetpack_widget_get_top_posts'), 10, 3); |
| 40 |
add_filter('grunion_contact_form_field_html', array(&$this, 'grunion_contact_form_field_html_filter'), 10, 3); |
| 41 |
add_filter('jetpack_open_graph_tags', array(&$this, 'jetpack_ogp')); |
| 42 |
} |
| 43 |
|
| 44 |
/* |
| 45 |
* access to the single instance of the class |
| 46 |
* |
| 47 |
* @since 1.7 |
| 48 |
* |
| 49 |
* @return object |
| 50 |
*/ |
| 51 |
static public function instance() { |
| 52 |
if (empty(self::$instance)) |
| 53 |
self::$instance = new self(); |
| 54 |
|
| 55 |
return self::$instance; |
| 56 |
} |
| 57 |
|
| 58 |
/* |
| 59 |
* WordPress Importer |
| 60 |
* if WordPress Importer is active, replace the wordpress_importer_init function |
| 61 |
* |
| 62 |
* @since 1.2 |
| 63 |
*/ |
| 64 |
function maybe_wordpress_importer() { |
| 65 |
if (defined('WP_LOAD_IMPORTERS') && class_exists('WP_Import')) { |
| 66 |
remove_action('admin_init', 'wordpress_importer_init'); |
| 67 |
add_action('admin_init', array(&$this, 'wordpress_importer_init')); |
| 68 |
} |
| 69 |
} |
| 70 |
|
| 71 |
/* |
| 72 |
* WordPress Importer |
| 73 |
* loads our child class PLL_WP_Import instead of WP_Import |
| 74 |
* |
| 75 |
* @since 1.2 |
| 76 |
*/ |
| 77 |
function wordpress_importer_init() { |
| 78 |
$class = new ReflectionClass('WP_Import'); |
| 79 |
load_plugin_textdomain( 'wordpress-importer', false, basename(dirname( $class->getFileName() )) . '/languages' ); |
| 80 |
|
| 81 |
$GLOBALS['wp_import'] = new PLL_WP_Import(); |
| 82 |
register_importer( 'wordpress', 'WordPress', __('Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'wordpress-importer'), array( $GLOBALS['wp_import'], 'dispatch' ) ); |
| 83 |
} |
| 84 |
|
| 85 |
/* |
| 86 |
* WordPress SEO by Yoast |
| 87 |
* translate options |
| 88 |
* add specific filters and actions |
| 89 |
* |
| 90 |
* @since 1.6.4 |
| 91 |
*/ |
| 92 |
public function wpseo_init() { |
| 93 |
global $polylang; |
| 94 |
|
| 95 |
if (!defined('WPSEO_VERSION') || PLL_ADMIN) |
| 96 |
return; |
| 97 |
|
| 98 |
// reloads options once the language has been defined to enable translations |
| 99 |
// useful only when the language is set from content |
| 100 |
if (did_action('wp_loaded')) { |
| 101 |
if (version_compare(WPSEO_VERSION, '1.7.2', '<')) { |
| 102 |
global $wpseo_front; |
| 103 |
} |
| 104 |
else { |
| 105 |
$wpseo_front = WPSEO_Frontend::get_instance(); |
| 106 |
} |
| 107 |
|
| 108 |
$options = version_compare(WPSEO_VERSION, '1.5', '<') ? get_wpseo_options_arr() : WPSEO_Options::get_option_names(); |
| 109 |
foreach ( $options as $opt ) |
| 110 |
$wpseo_front->options = array_merge( $wpseo_front->options, (array) get_option( $opt ) ); |
| 111 |
} |
| 112 |
|
| 113 |
// one sitemap per language when using multiple domains or subdomains |
| 114 |
// because WPSEO does not accept several domains or subdomains in one sitemap |
| 115 |
if ($polylang->options['force_lang'] > 1) { |
| 116 |
add_filter('home_url', array(&$this, 'wpseo_home_url'), 10, 2); // fix home_url |
| 117 |
add_filter('wpseo_posts_join', array(&$this, 'wpseo_posts_join'), 10, 2); |
| 118 |
add_filter('wpseo_posts_where', array(&$this, 'wpseo_posts_where'), 10, 2); |
| 119 |
} |
| 120 |
|
| 121 |
// one sitemap for all languages when the language is set from the content or directory name |
| 122 |
else { |
| 123 |
add_filter('get_terms_args', array(&$this, 'wpseo_remove_terms_filter')); |
| 124 |
} |
| 125 |
|
| 126 |
add_filter('pll_home_url_white_list', create_function('$arr', "return array_merge(\$arr, array(array('file' => 'wordpress-seo')));")); |
| 127 |
add_action('wpseo_opengraph', array(&$this, 'wpseo_ogp'), 2); |
| 128 |
} |
| 129 |
|
| 130 |
/* |
| 131 |
* WordPress SEO by Yoast |
| 132 |
* fixes the home url as well as the stylesheet url |
| 133 |
* only when using multiple domains or subdomains |
| 134 |
* |
| 135 |
* @since 1.6.4 |
| 136 |
* |
| 137 |
* @param string $url |
| 138 |
* @return $url |
| 139 |
*/ |
| 140 |
public function wpseo_home_url($url, $path) { |
| 141 |
global $polylang; |
| 142 |
|
| 143 |
$uri = empty($path) ? ltrim($_SERVER['REQUEST_URI'], '/') : $path; |
| 144 |
|
| 145 |
if ('sitemap_index.xml' === $uri || preg_match('#([^/]+?)-sitemap([0-9]+)?\.xml|([a-z]+)?-?sitemap\.xsl#', $uri)) |
| 146 |
$url = $polylang->links_model->switch_language_in_link($url, $polylang->curlang); |
| 147 |
|
| 148 |
return $url; |
| 149 |
} |
| 150 |
|
| 151 |
/* |
| 152 |
* WordPress SEO by Yoast |
| 153 |
* modifies the sql request for posts sitemaps |
| 154 |
* only when using multiple domains or subdomains |
| 155 |
* |
| 156 |
* @since 1.6.4 |
| 157 |
* |
| 158 |
* @param string $sql join clause |
| 159 |
* @param string $post_type |
| 160 |
* @return string |
| 161 |
*/ |
| 162 |
public function wpseo_posts_join($sql, $post_type) { |
| 163 |
global $polylang; |
| 164 |
return pll_is_translated_post_type($post_type) ? $sql. $polylang->model->join_clause('post') : $sql; |
| 165 |
} |
| 166 |
|
| 167 |
/* |
| 168 |
* WordPress SEO by Yoast |
| 169 |
* modifies the sql request for posts sitemaps |
| 170 |
* only when using multiple domains or subdomains |
| 171 |
* |
| 172 |
* @since 1.6.4 |
| 173 |
* |
| 174 |
* @param string $sql where clause |
| 175 |
* @param string $post_type |
| 176 |
* @return string |
| 177 |
*/ |
| 178 |
public function wpseo_posts_where($sql, $post_type) { |
| 179 |
global $polylang; |
| 180 |
return pll_is_translated_post_type($post_type) ? $sql . $polylang->model->where_clause($polylang->curlang, 'post') : $sql; |
| 181 |
} |
| 182 |
|
| 183 |
/* |
| 184 |
* WordPress SEO by Yoast |
| 185 |
* removes the language filter for the taxonomy sitemaps |
| 186 |
* only when the language is set from the content or directory name |
| 187 |
* |
| 188 |
* @since 1.0.3 |
| 189 |
* |
| 190 |
* @param array $args get_terms arguments |
| 191 |
* @return array modified list of arguments |
| 192 |
*/ |
| 193 |
public function wpseo_remove_terms_filter($args) { |
| 194 |
if (isset($GLOBALS['wp_query']->query['sitemap'])) |
| 195 |
$args['lang'] = 0; |
| 196 |
return $args; |
| 197 |
} |
| 198 |
|
| 199 |
/* |
| 200 |
* WordPress SEO by Yoast |
| 201 |
* adds opengraph support for translations |
| 202 |
* |
| 203 |
* @since 1.6 |
| 204 |
*/ |
| 205 |
public function wpseo_ogp() { |
| 206 |
global $polylang, $wpseo_og; |
| 207 |
|
| 208 |
// WPSEO already deals with the locale |
| 209 |
if (isset($polylang) && method_exists($wpseo_og, 'og_tag')) { |
| 210 |
foreach ($polylang->model->get_languages_list() as $language) { |
| 211 |
if ($language->slug != $polylang->curlang->slug && $polylang->links->get_translation_url($language) && $fb_locale = self::get_fb_locale($language)) { |
| 212 |
$wpseo_og->og_tag('og:locale:alternate', $fb_locale); |
| 213 |
} |
| 214 |
} |
| 215 |
} |
| 216 |
} |
| 217 |
|
| 218 |
/* |
| 219 |
* Custom field template does check $_REQUEST['post'] to populate the custom fields values |
| 220 |
* |
| 221 |
* @since 1.0.2 |
| 222 |
* |
| 223 |
* @param string $post_type unused |
| 224 |
* @param object $post current post object |
| 225 |
*/ |
| 226 |
public function cft_copy($post_type, $post) { |
| 227 |
global $custom_field_template; |
| 228 |
if (isset($custom_field_template, $_REQUEST['from_post'], $_REQUEST['new_lang']) && !empty($post)) |
| 229 |
$_REQUEST['post'] = $post->ID; |
| 230 |
} |
| 231 |
|
| 232 |
/* |
| 233 |
* rewrites the function Featured_Content::get_featured_post_ids() |
| 234 |
* |
| 235 |
* @since 1.4 |
| 236 |
* |
| 237 |
* @param array $ids featured posts ids |
| 238 |
* @return array modified featured posts ids (include all languages) |
| 239 |
*/ |
| 240 |
public function twenty_fourteen_featured_content_ids($featured_ids) { |
| 241 |
global $polylang; |
| 242 |
|
| 243 |
if (empty($polylang) || false !== $featured_ids) |
| 244 |
return $featured_ids; |
| 245 |
|
| 246 |
$settings = Featured_Content::get_setting(); |
| 247 |
|
| 248 |
if (!$term = get_term_by( 'name', $settings['tag-name'], 'post_tag' )) |
| 249 |
return $featured_ids; |
| 250 |
|
| 251 |
// get featured tag translations |
| 252 |
$tags = $polylang->model->get_translations('term' ,$term->term_id); |
| 253 |
$ids = array(); |
| 254 |
|
| 255 |
// Query for featured posts in all languages |
| 256 |
// one query per language to get the correct number of posts per language |
| 257 |
foreach ($tags as $tag) { |
| 258 |
$_ids = get_posts(array( |
| 259 |
'lang' => 0, // avoid language filters |
| 260 |
'fields' => 'ids', |
| 261 |
'numberposts' => Featured_Content::$max_posts, |
| 262 |
'tax_query' => array(array( |
| 263 |
'taxonomy' => 'post_tag', |
| 264 |
'terms' => (int) $tag, |
| 265 |
)), |
| 266 |
)); |
| 267 |
|
| 268 |
$ids = array_merge($ids, $_ids); |
| 269 |
} |
| 270 |
|
| 271 |
$ids = array_map( 'absint', $ids ); |
| 272 |
set_transient( 'featured_content_ids', $ids ); |
| 273 |
|
| 274 |
return $ids; |
| 275 |
} |
| 276 |
|
| 277 |
/* |
| 278 |
* translates the featured tag id in featured content settings |
| 279 |
* mainly to allow hiding it when requested in featured content options |
| 280 |
* acts only on frontend |
| 281 |
* |
| 282 |
* @since 1.4 |
| 283 |
* |
| 284 |
* @param array $settings featured content settings |
| 285 |
* @return array modified $settings |
| 286 |
*/ |
| 287 |
public function twenty_fourteen_option_featured_content($settings) { |
| 288 |
if (!PLL_ADMIN && $settings['tag-id'] && $tr = pll_get_term($settings['tag-id'])) |
| 289 |
$settings['tag-id'] = $tr; |
| 290 |
|
| 291 |
return $settings; |
| 292 |
} |
| 293 |
|
| 294 |
/* |
| 295 |
* adapted from the same function in jetpack-3.0.2/3rd-party/wpml.php |
| 296 |
* |
| 297 |
* @since 1.5.4 |
| 298 |
*/ |
| 299 |
public function jetpack_widget_get_top_posts( $posts, $post_ids, $count ) { |
| 300 |
foreach ( $posts as $k => $post ) { |
| 301 |
if (pll_current_language() !== pll_get_post_language($post['post_id'])) |
| 302 |
unset( $posts[ $k ] ); |
| 303 |
} |
| 304 |
|
| 305 |
return $posts; |
| 306 |
} |
| 307 |
|
| 308 |
/* |
| 309 |
* adapted from the same function in jetpack-3.0.2/3rd-party/wpml.php |
| 310 |
* keeps using 'icl_translate' as the function registers the string |
| 311 |
* |
| 312 |
* @since 1.5.4 |
| 313 |
*/ |
| 314 |
public function grunion_contact_form_field_html_filter( $r, $field_label, $id ){ |
| 315 |
if ( function_exists( 'icl_translate' ) ) { |
| 316 |
if ( pll_current_language() !== pll_default_language() ) { |
| 317 |
$label_translation = icl_translate( 'jetpack ', $field_label . '_label', $field_label ); |
| 318 |
$r = str_replace( $field_label, $label_translation, $r ); |
| 319 |
} |
| 320 |
} |
| 321 |
|
| 322 |
return $r; |
| 323 |
} |
| 324 |
|
| 325 |
/* |
| 326 |
* adds opengraph support for locale and translations |
| 327 |
* |
| 328 |
* @since 1.6 |
| 329 |
* |
| 330 |
* @param array $tags opengraph tags to output |
| 331 |
* @return array |
| 332 |
*/ |
| 333 |
public function jetpack_ogp($tags) { |
| 334 |
global $polylang; |
| 335 |
|
| 336 |
if (isset($polylang)) { |
| 337 |
foreach ($polylang->model->get_languages_list() as $language) { |
| 338 |
if ($language->slug != $polylang->curlang->slug && $polylang->links->get_translation_url($language) && $fb_locale = self::get_fb_locale($language)) |
| 339 |
$tags['og:locale:alternate'][] = $fb_locale; |
| 340 |
if ($language->slug == $polylang->curlang->slug && $fb_locale = self::get_fb_locale($language)) |
| 341 |
$tags['og:locale'] = $fb_locale; |
| 342 |
} |
| 343 |
} |
| 344 |
return $tags; |
| 345 |
} |
| 346 |
|
| 347 |
/* |
| 348 |
* correspondance between WordPress locales and Facebook locales |
| 349 |
* @see http://wpcentral.io/internationalization/ |
| 350 |
* @see https://www.facebook.com/translations/FacebookLocales.xml |
| 351 |
* |
| 352 |
* @since 1.6 |
| 353 |
* |
| 354 |
* @param object $language |
| 355 |
* @return bool|string |
| 356 |
*/ |
| 357 |
static public function get_fb_locale($language) { |
| 358 |
static $facebook_locales = array( |
| 359 |
'af' => 'af_ZA', 'ar' => 'ar_AR', 'az' => 'az_AZ', 'bel' => 'be_BY', 'bg_BG' => 'bg_BG', 'bn_BD' => 'bn_IN', |
| 360 |
'bs_BA' => 'bs_BA', 'ca' => 'ca_ES', 'ckb' => 'ku_TR', 'cs_CZ' => 'cs_CZ', 'cy' => 'cy_GB', 'da_DK' => 'da_DK', |
| 361 |
'de_DE' => 'de_DE', 'el' => 'el_GR', 'en_US' => 'en_US', 'en_GB' => 'en_GB', 'eo' => 'eo_EO', 'es_CL' => 'es_LA', |
| 362 |
'es_CO' => 'es_LA', 'es_MX' => 'es_LA', 'es_PE' => 'es_LA', 'es_PR' => 'es_LA', 'es_VE' => 'es_LA', 'es_ES' => 'es_ES', |
| 363 |
'et' => 'et_EE', 'eu' => 'eu_ES', 'fa_IR' => 'fa_IR', 'fi' => 'fi_FI', 'fo' => 'fo_FO', 'fr_CA' => 'fr_CA', |
| 364 |
'fr_FR' => 'fr_FR', 'fy' => 'fy_NL', 'ga' => 'ga_IE', 'gl_ES' => 'gl_ES', 'gn' => 'gn_PY', 'gu_IN' => 'gu_IN', |
| 365 |
'he_IL' => 'he_IL', 'hi_IN' => 'hi_IN', 'hr' => 'hr_HR', 'hu_HU' => 'hu_HU', 'hy' => 'hy_AM', 'id_ID' => 'id_ID', |
| 366 |
'is_IS' => 'is_IS', 'it_IT' => 'it_IT', 'ja' => 'ja_JP', 'jv_ID' => 'jv_ID', 'ka_GE' => 'ka_GE', 'kk' => 'kk_KZ', |
| 367 |
'km' => 'km_kH', 'kn' => 'kn_IN', 'ko_KR' => 'ko_KR', 'lt_LT' => 'lt_LT', 'lv' => 'lv_LV', 'mk_MK' => 'mk_MK', |
| 368 |
'ml_IN' => 'ml_IN', 'mn' => 'mn_MN', 'mr' => 'mr_IN', 'ms_MY' => 'ms_MY', 'ne_NP' => 'ne_NP', 'nb_NO' => 'nb_NO', |
| 369 |
'nl_NL' => 'nl_NL', 'nn_NO' => 'nn_NO', 'pa_IN' => 'pa_IN', 'pl_PL' => 'pl_PL', 'ps' => 'ps_AF', 'pt_BR' => 'pt_BR', |
| 370 |
'pt_PT' => 'pt_PT', 'ps' => 'ps_AF', 'ro_RO' => 'ro_RO', 'ru_RU' => 'ru_RU', 'si_LK' => 'si_LK', 'sk_SK' => 'sk_SK', |
| 371 |
'sl_SI' => 'sl_SI', 'sq' => 'sq_AL', 'sr_RS' => 'sr_RS', 'sv_SE' => 'sv_SE', 'sw' => 'sw_KE', 'ta_IN' => 'ta_IN', |
| 372 |
'te' => 'te_IN', 'tg' => 'tg_TJ', 'th' => 'th_TH', 'ph' => 'tl_PH', 'tr_TR' => 'tr_TR', 'uk' => 'uk_UA', |
| 373 |
'ur' => 'ur_PK', 'uz_UZ' => 'uz_UZ', 'vi' => 'vi_VN', 'zh_CN' => 'zh_CN', 'zh_HK' => 'zh_HK', 'zh_TW' => 'zh_TW' |
| 374 |
); |
| 375 |
|
| 376 |
return isset($facebook_locales[$language->locale]) ? $facebook_locales[$language->locale] : false; |
| 377 |
} |
| 378 |
} |
| 379 |
|