PluginProbe
Polylang / 2.7.2
Polylang v2.7.2
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 / modules / plugins / plugins-compat.php

plugins-compat.php in Polylang 2.7.2, at modules/plugins/plugins-compat.php

346 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 protected static $instance; // for singleton
11
12 /**
13 * Constructor
14 *
15 * @since 1.0
16 */
17 protected function __construct() {
18 add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 0 );
19 add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
20
21 // WordPress Importer
22 add_action( 'init', array( $this, 'maybe_wordpress_importer' ) );
23 add_filter( 'wp_import_terms', array( $this, 'wp_import_terms' ) );
24
25 // YARPP
26 add_action( 'init', array( $this, 'yarpp_init' ) ); // after Polylang has registered its taxonomy in setup_theme
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', array( $this, 'aq_home_url_black_list' ) );
33
34 // Duplicate post
35 add_filter( 'option_duplicate_post_taxonomies_blacklist', array( $this, 'duplicate_post_taxonomies_blacklist' ) );
36
37 // Jetpack
38 $this->jetpack = new PLL_Jetpack(); // Must be loaded before the plugin is active
39 add_action( 'pll_init', array( $this->featured_content = new PLL_Featured_Content(), 'init' ) );
40
41 // WP Sweep
42 add_filter( 'wp_sweep_excluded_taxonomies', array( $this, 'wp_sweep_excluded_taxonomies' ) );
43
44 // Twenty Seventeen
45 add_action( 'init', array( $this, 'twenty_seventeen_init' ) );
46
47 // No category base (works for Yoast SEO too)
48 add_filter( 'get_terms_args', array( $this, 'no_category_base_get_terms_args' ), 5 ); // Before adding cache domain
49
50 // WordPress MU Domain Mapping
51 if ( function_exists( 'redirect_to_mapped_domain' ) ) {
52 if ( ! defined( 'PLL_CACHE_HOME_URL' ) && ( $options = get_option( 'polylang' ) ) && $options['force_lang'] < 2 ) {
53 define( 'PLL_CACHE_HOME_URL', false );
54 }
55
56 if ( ! get_site_option( 'dm_no_primary_domain' ) ) {
57 remove_action( 'template_redirect', 'redirect_to_mapped_domain' );
58 add_action( 'template_redirect', array( $this, 'dm_redirect_to_mapped_domain' ) );
59 }
60 }
61 }
62
63 /**
64 * Access to the single instance of the class
65 *
66 * @since 1.7
67 *
68 * @return object
69 */
70 public static function instance() {
71 if ( empty( self::$instance ) ) {
72 self::$instance = new self();
73 }
74
75 return self::$instance;
76 }
77
78 /**
79 * Look for active plugins and load compatibility layer if needed
80 *
81 * @since 2.3
82 */
83 public function plugins_loaded() {
84 // Yoast SEO
85 if ( defined( 'WPSEO_VERSION' ) ) {
86 add_action( 'pll_init', array( $this->wpseo = new PLL_WPSEO(), 'init' ) );
87 }
88
89 if ( pll_is_cache_active() ) {
90 add_action( 'pll_init', array( $this->cache_compat = new PLL_Cache_Compat(), 'init' ) );
91 }
92
93 // Custom Post Type UI
94 if ( defined( 'CPTUI_VERSION' ) && class_exists( 'PLL_CPTUI' ) ) {
95 add_action( 'pll_init', array( $this->cptui = new PLL_CPTUI(), 'init' ) );
96 }
97
98 // The Event Calendar
99 if ( defined( 'TRIBE_EVENTS_FILE' ) && class_exists( 'PLL_TEC' ) ) {
100 add_action( 'pll_init', array( $this->tec = new PLL_TEC(), 'init' ) );
101 }
102
103 // Beaver Builder
104 if ( class_exists( 'FLBuilderLoader' ) && class_exists( 'PLL_FLBuilder' ) ) {
105 $this->flbuilder = new PLL_FLBuilder();
106 }
107
108 // Divi Builder
109 if ( ( 'Divi' === get_template() || defined( 'ET_BUILDER_PLUGIN_VERSION' ) ) && class_exists( 'PLL_Divi_Builder' ) ) {
110 $this->divi_builder = new PLL_Divi_Builder();
111 }
112
113 // WP Offload Media Lite
114 if ( function_exists( 'as3cf_init' ) && class_exists( 'PLL_AS3CF' ) ) {
115 add_action( 'pll_init', array( $this->as3cf = new PLL_AS3CF(), 'init' ) );
116 }
117
118 // Content Blocks (Custom Post Widget)
119 if ( function_exists( 'custom_post_widget_plugin_init' ) && class_exists( 'PLL_Content_Blocks' ) ) {
120 add_action( 'pll_init', array( $this->content_blocks = new PLL_Content_Blocks(), 'init' ) );
121 }
122 }
123
124 /**
125 * Look for active plugins and load compatibility layer after the theme has been setup
126 *
127 * @since 2.3.8
128 */
129 public function after_setup_theme() {
130 // Advanced Custom Fields Pro
131 if ( defined( 'ACF_VERSION' ) && version_compare( ACF_VERSION, '5.7.11', '>=' ) && class_exists( 'PLL_ACF' ) ) {
132 add_action( 'init', array( $this->acf = new PLL_ACF(), 'init' ) );
133 }
134
135 // Admin Columns & Admin Columns Pro
136 if ( did_action( 'pll_init' ) && ( defined( 'AC_FILE' ) || defined( 'ACP_FILE' ) ) && class_exists( 'PLL_CPAC' ) ) {
137 add_action( 'admin_init', array( $this->cpac = new PLL_CPAC(), 'init' ) );
138 }
139 }
140
141 /**
142 * WordPress Importer
143 * If WordPress Importer is active, replace the wordpress_importer_init function
144 *
145 * @since 1.2
146 */
147 public function maybe_wordpress_importer() {
148 if ( defined( 'WP_LOAD_IMPORTERS' ) && class_exists( 'WP_Import' ) ) {
149 remove_action( 'admin_init', 'wordpress_importer_init' );
150 add_action( 'admin_init', array( $this, 'wordpress_importer_init' ) );
151 }
152 }
153
154 /**
155 * WordPress Importer
156 * Loads our child class PLL_WP_Import instead of WP_Import
157 *
158 * @since 1.2
159 */
160 public function wordpress_importer_init() {
161 $class = new ReflectionClass( 'WP_Import' );
162 load_plugin_textdomain( 'wordpress-importer', false, basename( dirname( $class->getFileName() ) ) . '/languages' );
163
164 $GLOBALS['wp_import'] = new PLL_WP_Import();
165 register_importer( 'wordpress', 'WordPress', __( 'Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'polylang' ), array( $GLOBALS['wp_import'], 'dispatch' ) ); // phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
166 }
167
168 /**
169 * WordPress Importer
170 * Backward Compatibility Polylang < 1.8
171 * Sets the flag when importing a language and the file has been exported with Polylang < 1.8
172 *
173 * @since 1.8
174 *
175 * @param array $terms an array of arrays containing terms information form the WXR file
176 * @return array
177 */
178 public function wp_import_terms( $terms ) {
179 $languages = include PLL_SETTINGS_INC . '/languages.php';
180
181 foreach ( $terms as $key => $term ) {
182 if ( 'language' === $term['term_taxonomy'] ) {
183 $description = maybe_unserialize( $term['term_description'] );
184 if ( empty( $description['flag_code'] ) && isset( $languages[ $description['locale'] ] ) ) {
185 $description['flag_code'] = $languages[ $description['locale'] ]['flag'];
186 $terms[ $key ]['term_description'] = maybe_serialize( $description );
187 }
188 }
189 }
190 return $terms;
191 }
192
193 /**
194 * YARPP
195 * Just makes YARPP aware of the language taxonomy ( after Polylang registered it )
196 *
197 * @since 1.0
198 */
199 public function yarpp_init() {
200 $GLOBALS['wp_taxonomies']['language']->yarpp_support = 1;
201 }
202
203 /**
204 * Aqua Resizer
205 *
206 * @since 1.1.5
207 *
208 * @param array $arr
209 * @return array
210 */
211 public function aq_home_url_black_list( $arr ) {
212 return array_merge( $arr, array( array( 'function' => 'aq_resize' ) ) );
213 }
214
215 /**
216 * Custom field template
217 * Custom field template does check $_REQUEST['post'] to populate the custom fields values
218 *
219 * @since 1.0.2
220 *
221 * @param string $post_type unused
222 * @param object $post current post object
223 */
224 public function cft_copy( $post_type, $post ) {
225 global $custom_field_template;
226 if ( isset( $custom_field_template, $_REQUEST['from_post'], $_REQUEST['new_lang'] ) && ! empty( $post ) ) { // phpcs:ignore WordPress.Security.NonceVerification
227 $_REQUEST['post'] = $post->ID;
228 }
229 }
230
231 /**
232 * Duplicate Post
233 * Avoid duplicating the 'post_translations' taxonomy
234 *
235 * @since 1.8
236 *
237 * @param array|string $taxonomies
238 * @return array
239 */
240 public function duplicate_post_taxonomies_blacklist( $taxonomies ) {
241 if ( empty( $taxonomies ) ) {
242 $taxonomies = array(); // As we get an empty string when there is no taxonomy
243 }
244
245 $taxonomies[] = 'post_translations';
246 return $taxonomies;
247 }
248
249 /**
250 * WP Sweep
251 * Add 'term_language' and 'term_translations' to excluded taxonomies otherwise terms loose their language and translation group
252 *
253 * @since 2.0
254 *
255 * @param array $excluded_taxonomies list of taxonomies excluded from sweeping
256 * @return array
257 */
258 public function wp_sweep_excluded_taxonomies( $excluded_taxonomies ) {
259 return array_merge( $excluded_taxonomies, array( 'term_language', 'term_translations' ) );
260 }
261
262 /**
263 * Twenty Seventeen
264 * Translates the front page panels
265 *
266 * @since 2.0.10
267 */
268 public function twenty_seventeen_init() {
269 if ( 'twentyseventeen' === get_template() && did_action( 'pll_init' ) ) {
270 if ( function_exists( 'twentyseventeen_panel_count' ) && PLL() instanceof PLL_Frontend ) {
271 $num_sections = twentyseventeen_panel_count();
272 for ( $i = 1; $i < ( 1 + $num_sections ); $i++ ) {
273 add_filter( 'theme_mod_panel_' . $i, 'pll_get_post' );
274 }
275 }
276
277 if ( PLL() instanceof PLL_Frontend ) {
278 add_filter( 'theme_mod_external_header_video', 'pll__' );
279 } else {
280 pll_register_string( __( 'Header video', 'polylang' ), get_theme_mod( 'external_header_video' ), 'Twenty Seventeen', false );
281 }
282 }
283 }
284
285 /**
286 * Make sure No category base plugins (including Yoast SEO) get all categories when flushing rules
287 *
288 * @since 2.1
289 *
290 * @param array $args
291 * @return array
292 */
293 public function no_category_base_get_terms_args( $args ) {
294 if ( doing_filter( 'category_rewrite_rules' ) ) {
295 $args['lang'] = '';
296 }
297 return $args;
298 }
299
300 /**
301 * WordPress MU Domain Mapping
302 * Fix primary domain check which forces only one domain per blog
303 * Accept only known domains/subdomains for the current blog
304 *
305 * @since 2.2
306 */
307 public function dm_redirect_to_mapped_domain() {
308 $options = get_option( 'polylang' );
309
310 // The language is set from the subdomain or domain name
311 if ( $options['force_lang'] > 1 ) {
312 // Don't redirect the main site
313 if ( is_main_site() ) {
314 return;
315 }
316
317 // Don't redirect post previews
318 if ( isset( $_GET['preview'] ) && 'true' === $_GET['preview'] ) { // phpcs:ignore WordPress.Security.NonceVerification
319 return;
320 }
321
322 // Don't redirect theme customizer
323 if ( isset( $_POST['customize'] ) && isset( $_POST['theme'] ) && 'on' === $_POST['customize'] ) { // phpcs:ignore WordPress.Security.NonceVerification
324 return;
325 }
326
327 // If we can't associate the requested domain to a language, redirect to the default domain
328 $requested_url = pll_get_requested_url();
329 $requested_host = wp_parse_url( $requested_url, PHP_URL_HOST );
330
331 $hosts = PLL()->links_model->get_hosts();
332 $lang = array_search( $requested_host, $hosts );
333
334 if ( empty( $lang ) ) {
335 $status = get_site_option( 'dm_301_redirect' ) ? '301' : '302'; // Honor status redirect option
336 $redirect = str_replace( '://' . $requested_host, '://' . $hosts[ $options['default_lang'] ], $requested_url );
337 wp_safe_redirect( $redirect, $status );
338 exit;
339 }
340 } else {
341 // Otherwise rely on MU Domain Mapping
342 redirect_to_mapped_domain();
343 }
344 }
345 }
346