PluginProbe
Polylang / 3.2.2
Polylang v3.2.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 / include / class-polylang.php

class-polylang.php in Polylang 3.2.2, at include/class-polylang.php

264 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Don't access directly
8 };
9
10 // Default directory to store user data such as custom flags
11 if ( ! defined( 'PLL_LOCAL_DIR' ) ) {
12 define( 'PLL_LOCAL_DIR', WP_CONTENT_DIR . '/polylang' );
13 }
14
15 // Includes local config file if exists
16 if ( file_exists( PLL_LOCAL_DIR . '/pll-config.php' ) ) {
17 include_once PLL_LOCAL_DIR . '/pll-config.php';
18 }
19
20 /**
21 * Controls the plugin, as well as activation, and deactivation
22 *
23 * @since 0.1
24 */
25 class Polylang {
26
27 /**
28 * Constructor
29 *
30 * @since 0.1
31 */
32 public function __construct() {
33 require_once __DIR__ . '/functions.php'; // VIP functions
34
35 // register an action when plugin is activating.
36 register_activation_hook( POLYLANG_BASENAME, array( 'PLL_Wizard', 'start_wizard' ) );
37
38 $install = new PLL_Install( POLYLANG_BASENAME );
39
40 // Stopping here if we are going to deactivate the plugin ( avoids breaking rewrite rules )
41 if ( $install->is_deactivation() || ! $install->can_activate() ) {
42 return;
43 }
44
45 // Plugin initialization
46 // Take no action before all plugins are loaded
47 add_action( 'plugins_loaded', array( $this, 'init' ), 1 );
48
49 // Override load text domain waiting for the language to be defined
50 // Here for plugins which load text domain as soon as loaded :(
51 if ( ! defined( 'PLL_OLT' ) || PLL_OLT ) {
52 PLL_OLT_Manager::instance();
53 }
54
55 /*
56 * Loads the compatibility with some plugins and themes.
57 * Loaded as soon as possible as we may need to act before other plugins are loaded.
58 */
59 if ( ! defined( 'PLL_PLUGINS_COMPAT' ) || PLL_PLUGINS_COMPAT ) {
60 PLL_Integrations::instance();
61 }
62 }
63
64 /**
65 * Tells whether the current request is an ajax request on frontend or not
66 *
67 * @since 2.2
68 *
69 * @return bool
70 */
71 public static function is_ajax_on_front() {
72 // Special test for plupload which does not use jquery ajax and thus does not pass our ajax prefilter
73 // Special test for customize_save done in frontend but for which we want to load the admin
74 $in = isset( $_REQUEST['action'] ) && in_array( sanitize_key( $_REQUEST['action'] ), array( 'upload-attachment', 'customize_save' ) ); // phpcs:ignore WordPress.Security.NonceVerification
75 $is_ajax_on_front = wp_doing_ajax() && empty( $_REQUEST['pll_ajax_backend'] ) && ! $in; // phpcs:ignore WordPress.Security.NonceVerification
76
77 /**
78 * Filters whether the current request is an ajax request on front.
79 *
80 * @since 2.3
81 *
82 * @param bool $is_ajax_on_front Whether the current request is an ajax request on front.
83 */
84 return apply_filters( 'pll_is_ajax_on_front', $is_ajax_on_front );
85 }
86
87 /**
88 * Is the current request a REST API request?
89 * Inspired by WP::parse_request()
90 * Needed because at this point, the constant REST_REQUEST is not defined yet
91 *
92 * @since 2.4.1
93 *
94 * @return bool
95 */
96 public static function is_rest_request() {
97 // Handle pretty permalinks.
98 $home_path = trim( (string) wp_parse_url( home_url(), PHP_URL_PATH ), '/' );
99 $home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) );
100
101 $req_uri = trim( (string) wp_parse_url( pll_get_requested_url(), PHP_URL_PATH ), '/' );
102 $req_uri = preg_replace( $home_path_regex, '', $req_uri );
103 $req_uri = trim( $req_uri, '/' );
104 $req_uri = str_replace( 'index.php', '', $req_uri );
105 $req_uri = trim( $req_uri, '/' );
106
107 // And also test rest_route query string parameter is not empty for plain permalinks.
108 $query_string = array();
109 wp_parse_str( (string) wp_parse_url( pll_get_requested_url(), PHP_URL_QUERY ), $query_string );
110 $rest_route = isset( $query_string['rest_route'] ) ? trim( $query_string['rest_route'], '/' ) : false;
111
112 return 0 === strpos( $req_uri, rest_get_url_prefix() . '/' ) || ! empty( $rest_route );
113 }
114
115 /**
116 * Tells if we are in the wizard process.
117 *
118 * @since 2.7
119 *
120 * @return bool
121 */
122 public static function is_wizard() {
123 return isset( $_GET['page'] ) && ! empty( $_GET['page'] ) && 'mlang_wizard' === sanitize_key( $_GET['page'] ); // phpcs:ignore WordPress.Security.NonceVerification
124 }
125
126 /**
127 * Defines constants
128 * May be overridden by a plugin if set before plugins_loaded, 1
129 *
130 * @since 1.6
131 *
132 * @return void
133 */
134 public static function define_constants() {
135 // Cookie name. no cookie will be used if set to false
136 if ( ! defined( 'PLL_COOKIE' ) ) {
137 define( 'PLL_COOKIE', 'pll_language' );
138 }
139
140 // Backward compatibility with Polylang < 2.3
141 if ( ! defined( 'PLL_AJAX_ON_FRONT' ) ) {
142 define( 'PLL_AJAX_ON_FRONT', self::is_ajax_on_front() );
143 }
144
145 // Admin
146 if ( ! defined( 'PLL_ADMIN' ) ) {
147 define( 'PLL_ADMIN', wp_doing_cron() || ( defined( 'WP_CLI' ) && WP_CLI ) || ( is_admin() && ! PLL_AJAX_ON_FRONT ) );
148 }
149
150 // Settings page whatever the tab except for the wizard which needs to be an admin process.
151 if ( ! defined( 'PLL_SETTINGS' ) ) {
152 define( 'PLL_SETTINGS', is_admin() && ( ( isset( $_GET['page'] ) && 0 === strpos( sanitize_key( $_GET['page'] ), 'mlang' ) && ! self::is_wizard() ) || ! empty( $_REQUEST['pll_ajax_settings'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
153 }
154 }
155
156 /**
157 * Polylang initialization
158 * setups models and separate admin and frontend
159 *
160 * @since 1.2
161 *
162 * @return void
163 */
164 public function init() {
165 global $polylang;
166
167 self::define_constants();
168 $options = get_option( 'polylang' );
169
170 // Plugin upgrade
171 if ( $options && version_compare( $options['version'], POLYLANG_VERSION, '<' ) ) {
172 $upgrade = new PLL_Upgrade( $options );
173 if ( ! $upgrade->upgrade() ) { // If the version is too old
174 return;
175 }
176 }
177
178 // In some edge cases, it's possible that no options were found in the database. Load default options as we need some.
179 if ( ! $options ) {
180 $options = PLL_Install::get_default_options();
181 }
182
183 // Make sure that this filter is *always* added before PLL_Model::get_languages_list() is called for the first time
184 add_filter( 'pll_languages_list', array( 'PLL_Static_Pages', 'pll_languages_list' ), 2, 2 ); // Before PLL_Links_Model
185
186 /**
187 * Filter the model class to use
188 * /!\ this filter is fired *before* the $polylang object is available
189 *
190 * @since 1.5
191 *
192 * @param string $class either PLL_Model or PLL_Admin_Model
193 */
194 $class = apply_filters( 'pll_model', PLL_SETTINGS || self::is_wizard() ? 'PLL_Admin_Model' : 'PLL_Model' );
195 $model = new $class( $options );
196 $links_model = $model->get_links_model();
197
198 if ( ! $model->get_languages_list() ) {
199 /**
200 * Fires when no language has been defined yet
201 * Used to load overridden textdomains
202 *
203 * @since 1.2
204 */
205 do_action( 'pll_no_language_defined' );
206 }
207
208 $class = '';
209
210 if ( PLL_SETTINGS ) {
211 $class = 'PLL_Settings';
212 } elseif ( PLL_ADMIN ) {
213 $class = 'PLL_Admin';
214 } elseif ( self::is_rest_request() ) {
215 $class = 'PLL_REST_Request';
216 } elseif ( $model->get_languages_list() ) {
217 $class = 'PLL_Frontend';
218 }
219
220 /**
221 * Filters the class to use to instantiate the $polylang object
222 *
223 * @since 2.6
224 *
225 * @param string $class A class name.
226 */
227 $class = apply_filters( 'pll_context', $class );
228
229 if ( ! empty( $class ) ) {
230 $polylang = new $class( $links_model );
231
232 /**
233 * Fires after the $polylang object is created and before the API is loaded
234 *
235 * @since 2.0
236 *
237 * @param object $polylang
238 */
239 do_action_ref_array( 'pll_pre_init', array( &$polylang ) );
240
241 require_once __DIR__ . '/api.php'; // Loads the API
242
243 // Loads the modules.
244 $load_scripts = glob( POLYLANG_DIR . '/modules/*/load.php', GLOB_NOSORT );
245 if ( is_array( $load_scripts ) ) {
246 foreach ( $load_scripts as $load_script ) {
247 require_once $load_script; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
248 }
249 }
250
251 $polylang->init();
252
253 /**
254 * Fires after the $polylang object and the API is loaded
255 *
256 * @since 1.7
257 *
258 * @param object $polylang
259 */
260 do_action_ref_array( 'pll_init', array( &$polylang ) );
261 }
262 }
263 }
264