PluginProbe
Polylang / 3.7.7
Polylang v3.7.7
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
← All changes | include/class-polylang.php +95 -47 2.8.43.7.7 View file →
@@ -2,11 +2,14 @@
2 2 /**
3 3 * @package Polylang
4 4 */
5 5
6 +use WP_Syntex\Polylang\Options\Options;
7 +use WP_Syntex\Polylang\Options\Registry as Options_Registry;
8 +
6 9 if ( ! defined( 'ABSPATH' ) ) {
7 10 exit; // Don't access directly
8 -};
11 +}
9 12
10 13 // Default directory to store user data such as custom flags
11 14 if ( ! defined( 'PLL_LOCAL_DIR' ) ) {
12 15 define( 'PLL_LOCAL_DIR', WP_CONTENT_DIR . '/polylang' );
@@ -12,9 +15,9 @@
12 15 define( 'PLL_LOCAL_DIR', WP_CONTENT_DIR . '/polylang' );
13 16 }
14 17
15 18 // Includes local config file if exists
16 -if ( file_exists( PLL_LOCAL_DIR . '/pll-config.php' ) ) {
19 +if ( is_readable( PLL_LOCAL_DIR . '/pll-config.php' ) ) {
17 20 include_once PLL_LOCAL_DIR . '/pll-config.php';
18 21 }
19 22
20 23 /**
@@ -20,8 +23,10 @@
20 23 /**
21 24 * Controls the plugin, as well as activation, and deactivation
22 25 *
23 26 * @since 0.1
27 + *
28 + * @template TPLLClass of PLL_Base
24 29 */
25 30 class Polylang {
26 31
27 32 /**
@@ -94,13 +99,13 @@
94 99 * @return bool
95 100 */
96 101 public static function is_rest_request() {
97 102 // Handle pretty permalinks.
98 - $home_path = trim( wp_parse_url( home_url(), PHP_URL_PATH ), '/' );
103 + $home_path = trim( (string) wp_parse_url( home_url(), PHP_URL_PATH ), '/' );
99 104 $home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) );
100 105
101 - $req_uri = trim( wp_parse_url( pll_get_requested_url(), PHP_URL_PATH ), '/' );
102 - $req_uri = preg_replace( $home_path_regex, '', $req_uri );
106 + $req_uri = trim( (string) wp_parse_url( pll_get_requested_url(), PHP_URL_PATH ), '/' );
107 + $req_uri = (string) preg_replace( $home_path_regex, '', $req_uri );
103 108 $req_uri = trim( $req_uri, '/' );
104 109 $req_uri = str_replace( 'index.php', '', $req_uri );
105 110 $req_uri = trim( $req_uri, '/' );
106 111
@@ -105,10 +110,10 @@
105 110 $req_uri = trim( $req_uri, '/' );
106 111
107 112 // And also test rest_route query string parameter is not empty for plain permalinks.
108 113 $query_string = array();
109 - wp_parse_str( 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;
114 + wp_parse_str( (string) wp_parse_url( pll_get_requested_url(), PHP_URL_QUERY ), $query_string );
115 + $rest_route = isset( $query_string['rest_route'] ) && is_string( $query_string['rest_route'] ) ? trim( $query_string['rest_route'], '/' ) : false;
111 116
112 117 return 0 === strpos( $req_uri, rest_get_url_prefix() . '/' ) || ! empty( $rest_route );
113 118 }
114 119
@@ -127,8 +132,10 @@
127 132 * Defines constants
128 133 * May be overridden by a plugin if set before plugins_loaded, 1
129 134 *
130 135 * @since 1.6
136 + *
137 + * @return void
131 138 */
132 139 public static function define_constants() {
133 140 // Cookie name. no cookie will be used if set to false
134 141 if ( ! defined( 'PLL_COOKIE' ) ) {
@@ -155,31 +162,31 @@
155 162 * Polylang initialization
156 163 * setups models and separate admin and frontend
157 164 *
158 165 * @since 1.2
166 + *
167 + * @return void
159 168 */
160 169 public function init() {
161 - global $polylang;
170 + self::define_constants();
162 171
163 - self::define_constants();
164 - $options = get_option( 'polylang' );
172 + // Plugin options.
173 + add_action( 'pll_init_options_for_blog', array( Options_Registry::class, 'register' ) );
174 + $options = new Options();
165 175
166 176 // Plugin upgrade
167 - if ( $options && version_compare( $options['version'], POLYLANG_VERSION, '<' ) ) {
168 - $upgrade = new PLL_Upgrade( $options );
169 - if ( ! $upgrade->upgrade() ) { // If the version is too old
170 - return;
177 + if ( ! empty( $options['version'] ) ) {
178 + if ( version_compare( $options['version'], POLYLANG_VERSION, '<' ) ) {
179 + $upgrade = new PLL_Upgrade( $options );
180 + if ( ! $upgrade->upgrade() ) { // If the version is too old
181 + return;
182 + }
171 183 }
184 + } else {
185 + // In some edge cases, it's possible that no options were found in the database.
186 + $options['version'] = POLYLANG_VERSION;
172 187 }
173 188
174 - // In some edge cases, it's possible that no options were found in the database. Load default options as we need some.
175 - if ( ! $options ) {
176 - $options = PLL_Install::get_default_options();
177 - }
178 -
179 - // Make sure that this filter is *always* added before PLL_Model::get_languages_list() is called for the first time
180 - add_filter( 'pll_languages_list', array( 'PLL_Static_Pages', 'pll_languages_list' ), 2, 2 ); // Before PLL_Links_Model
181 -
182 189 /**
183 190 * Filter the model class to use
184 191 * /!\ this filter is fired *before* the $polylang object is available
185 192 *
@@ -187,12 +194,12 @@
187 194 *
188 195 * @param string $class either PLL_Model or PLL_Admin_Model
189 196 */
190 197 $class = apply_filters( 'pll_model', PLL_SETTINGS || self::is_wizard() ? 'PLL_Admin_Model' : 'PLL_Model' );
198 + /** @var PLL_Model $model */
191 199 $model = new $class( $options );
192 - $links_model = $model->get_links_model();
193 200
194 - if ( ! $model->get_languages_list() ) {
201 + if ( ! $model->has_languages() ) {
195 202 /**
196 203 * Fires when no language has been defined yet
197 204 * Used to load overridden textdomains
198 205 *
@@ -208,9 +215,9 @@
208 215 } elseif ( PLL_ADMIN ) {
209 216 $class = 'PLL_Admin';
210 217 } elseif ( self::is_rest_request() ) {
211 218 $class = 'PLL_REST_Request';
212 - } elseif ( $model->get_languages_list() && empty( $_GET['deactivate-polylang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
219 + } elseif ( $model->has_languages() ) {
213 220 $class = 'PLL_Frontend';
214 221 }
215 222
216 223 /**
@@ -222,35 +229,76 @@
222 229 */
223 230 $class = apply_filters( 'pll_context', $class );
224 231
225 232 if ( ! empty( $class ) ) {
226 - $polylang = new $class( $links_model );
233 + /** @phpstan-var class-string<TPLLClass> $class */
234 + $this->init_context( $class, $model );
235 + }
236 + }
227 237
228 - /**
229 - * Fires after the $polylang object is created and before the API is loaded
230 - *
231 - * @since 2.0
232 - *
233 - * @param object $polylang
234 - */
235 - do_action_ref_array( 'pll_pre_init', array( &$polylang ) );
238 + /**
239 + * Polylang initialization.
240 + * Setups the Polylang Context, loads the modules and init Polylang.
241 + *
242 + * @since 3.6
243 + *
244 + * @param string $class The class name.
245 + * @param PLL_Model $model Instance of PLL_Model.
246 + * @return PLL_Base
247 + *
248 + * @phpstan-param class-string<TPLLClass> $class
249 + * @phpstan-return TPLLClass
250 + */
251 + public function init_context( string $class, PLL_Model $model ): PLL_Base {
252 + global $polylang;
236 253
237 - require_once __DIR__ . '/api.php'; // Loads the API
254 + $links_model = $model->get_links_model();
255 + $polylang = new $class( $links_model );
238 256
239 - // Loads the modules.
240 - foreach ( glob( POLYLANG_DIR . '/modules/*/load.php', GLOB_NOSORT ) as $load_script ) { // phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
257 + /**
258 + * Fires after Polylang's model init.
259 + * This is the best place to register a custom table (see `PLL_Model`'s constructor).
260 + * /!\ This hook is fired *before* the $polylang object is available.
261 + * /!\ The languages are also not available yet.
262 + *
263 + * @since 3.4
264 + *
265 + * @param PLL_Model $model Polylang model.
266 + */
267 + do_action( 'pll_model_init', $model );
268 +
269 + $model->maybe_create_language_terms();
270 +
271 + /**
272 + * Fires after the $polylang object is created and before the API is loaded
273 + *
274 + * @since 2.0
275 + *
276 + * @param object $polylang
277 + */
278 + do_action_ref_array( 'pll_pre_init', array( &$polylang ) );
279 +
280 + // Loads the API
281 + require_once POLYLANG_DIR . '/include/api.php';
282 +
283 + // Loads the modules.
284 + $load_scripts = glob( POLYLANG_DIR . '/modules/*/load.php', GLOB_NOSORT );
285 + if ( is_array( $load_scripts ) ) {
286 + foreach ( $load_scripts as $load_script ) {
241 287 require_once $load_script; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
242 288 }
289 + }
243 290
244 - $polylang->init();
291 + $polylang->init();
245 292
246 - /**
247 - * Fires after the $polylang object and the API is loaded
248 - *
249 - * @since 1.7
250 - *
251 - * @param object $polylang
252 - */
253 - do_action_ref_array( 'pll_init', array( &$polylang ) );
254 - }
293 + /**
294 + * Fires after the $polylang object and the API is loaded
295 + *
296 + * @since 1.7
297 + *
298 + * @param object $polylang
299 + */
300 + do_action_ref_array( 'pll_init', array( &$polylang ) );
301 +
302 + return $polylang;
255 303 }
256 304 }