PluginProbe
Plugin Load Filter / 4.4.0
Plugin Load Filter v4.4.0
trunk 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.3.1 2.4.0 2.4.1 2.5.1 3.3.0 4.0.6 4.1.1 4.2.0 4.3.0 4.3.1 4.4.0
plugin-load-filter / mu-plugins / plf-filter.php

plf-filter.php in Plugin Load Filter 4.4.0, at mu-plugins/plf-filter.php

1,554 lines 76.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: plugin load filter [plf-filter]
4 Description: Dynamically activated only plugins that you have selected in each page. [Note] plf-filter has been automatically installed / deleted by Activate / Deactivate of "load filter plugin".
5 Version: 4.4.0
6 Plugin URI: http://celtislab.net/en/wp-plugin-load-filter
7 Author: enomoto@celtislab
8 Author URI: http://celtislab.net/
9 License: GPLv2
10 */
11 defined( 'ABSPATH' ) || exit;
12
13 /***************************************************************************
14 * pluggable.php defined function overwrite
15 * pluggable.php read before the query_posts () is processed by the current user undetermined
16 **************************************************************************/
17 /**
18 * Gets hash of given string.
19 *
20 * @param string $data Plain text to hash.
21 * @return string Hash of $data.
22 */
23 //wp_salt( $scheme ) を簡略化して logged_in cookie 限定
24 function plf_logged_in_hash( $data, $algo = 'md5' ) {
25 $values = array(
26 'key' => '',
27 'salt' => '',
28 );
29 foreach ( array( 'key', 'salt' ) as $type ) {
30 $const = strtoupper( "logged_in_{$type}" );
31 if ( defined( $const ) && constant( $const ) ) {
32 $values[ $type ] = constant( $const );
33 }
34 }
35 $salt = $values['key'] . $values['salt'];
36
37 // Ensure the algorithm is supported by the hash_hmac function.
38 if ( ! in_array( $algo, hash_hmac_algos(), true ) ) {
39 throw new InvalidArgumentException(
40 sprintf(
41 esc_html( 'Unsupported hashing algorithm: %1$s. Supported algorithms are: %2$s' ),
42 esc_html($algo),
43 implode( ', ', esc_html(hash_hmac_algos()) )
44 )
45 );
46 }
47 return hash_hmac( $algo, $data, $salt );
48 }
49
50 //plf 用の $_GET, $_POST, $_REQUEST, $_COOKIE, $_SERVER サニタイズ
51 function plf_sanitize( $value, $type = 'text' ) {
52 if (is_array($value)) {
53 foreach ($value as $k => $v) {
54 $value[$k] = plf_sanitize($v, $type);
55 }
56 return $value;
57 }
58 // wp_magic_quotes() 判定
59 if (function_exists('did_action') && did_action('sanitize_comment_cookies')) {
60 $value = wp_unslash($value);
61 }
62 switch ($type) {
63 case 'text':
64 if (function_exists('sanitize_text_field')) {
65 return sanitize_text_field($value);
66 }
67 $value = (string)$value;
68 // phpcs:disable WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
69 $value = strip_tags($value);
70 $value = preg_replace('/[\r\n\t ]+/', ' ', $value);
71 $value = preg_replace('/[\x00-\x1F\x7F]/u', '', $value);
72 return trim($value);
73 case 'textarea':
74 if (function_exists('sanitize_textarea_field')) {
75 return sanitize_textarea_field($value);
76 }
77 $value = (string)$value;
78 // phpcs:disable WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
79 $value = strip_tags($value);
80 $value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $value);
81 return trim($value);
82 case 'url':
83 if (function_exists('esc_url_raw')) {
84 return esc_url_raw($value);
85 }
86 return filter_var($value, FILTER_SANITIZE_URL);
87 case 'int':
88 if (function_exists('absint')) {
89 return absint($value);
90 }
91 return (int)$value;
92 case 'bool':
93 if (function_exists('rest_sanitize_boolean')) {
94 return rest_sanitize_boolean($value);
95 }
96 return filter_var($value, FILTER_VALIDATE_BOOLEAN);
97 case 'key': //slug 等の識別子用 英数字、_- に限定
98 if (function_exists('sanitize_key')) {
99 return sanitize_key($value);
100 }
101 $value = strtolower((string)$value);
102 $value = preg_replace('/[^a-z0-9_\-]/', '', $value);
103 return $value;
104 default:
105 return $value;
106 }
107 }
108
109 if ( !function_exists('wp_get_current_user') ) :
110 /**
111 * Retrieve the current user object.
112 * @return WP_User Current user WP_User object
113 */
114 function wp_get_current_user() {
115 static $_current_user = null;
116 //ver4.2.1 Depending on the environment, a JS error may occur in the iframe in the Customizer, so an IFRAME_REQUEST check has been added.
117 if ( ! function_exists( 'wp_set_current_user' ) || (! defined( 'IFRAME_REQUEST') && did_action( 'setup_theme' ) === 0) ){
118 if ( defined( 'LOGGED_IN_COOKIE' ) && !empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) ) {
119 $login_cookie = plf_sanitize($_COOKIE[ LOGGED_IN_COOKIE ]);
120 $cookie_elements = explode( '|', $login_cookie );
121 if ( count( $cookie_elements ) === 4 ) {
122 list( $username, $expiration, $token, $hmac ) = $cookie_elements;
123 if ( $expiration > time() ) {
124 if (!empty($_current_user) && $_current_user->user_login === $username){
125 return $_current_user;
126 }
127 $user = get_user_by( 'login', $username );
128 if ( $user ) {
129 //WP6.8 bcrypt サポートにより $pass_frag が変更された
130 //$pass_frag = substr( $user->user_pass, 8, 4 );
131 if ( str_starts_with( $user->user_pass, '$P$' ) || str_starts_with( $user->user_pass, '$2y$' ) ) {
132 // Retain previous behaviour of phpass or vanilla bcrypt hashed passwords.
133 $pass_frag = substr( $user->user_pass, 8, 4 );
134 } else {
135 // Otherwise, use a substring from the end of the hash to avoid dealing with potentially long hash prefixes.
136 $pass_frag = substr( $user->user_pass, -4 );
137 }
138 $key = plf_logged_in_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token );
139 $hash = hash_hmac( 'sha256', $username . '|' . $expiration . '|' . $token, $key );
140
141 if ( hash_equals( $hash, $hmac ) ) {
142 $manager = WP_Session_Tokens::get_instance( $user->ID );
143 if ( $manager->verify( $token ) ) {
144 //この時点のユーザーは仮ユーザーデータであり $current_user は未設定とする
145 $_current_user = $user;
146 return $user;
147 }
148 }
149 }
150 }
151 }
152 }
153 //ver4.0.17 fixed https://wordpress.org/support/topic/wp_get_current_user-is-overridden/
154 //return 0;
155 $user = new WP_User( 0 );
156 return $user;
157
158 } else {
159 //$GLOBALS['wp_roles'] セット後の setup_theme アクション後に $current_user を設定する
160 //※使用プラグインの組み合わせにもよるが、想定外に早い $current_user 設定は bbpress 等の一部プラグインにおいて capability 動的追加が反映されないことがあるため
161 return _wp_get_current_user();
162 }
163 }
164 endif;
165
166 if ( !function_exists('get_userdata') ) :
167 /**
168 * Retrieve user info by user ID.
169 * @param int $user_id User ID
170 * @return WP_User|bool WP_User object on success, false on failure.
171 */
172 function get_userdata( $user_id ) {
173 return get_user_by( 'id', $user_id );
174 }
175 endif;
176
177 if ( !function_exists('get_user_by') ) :
178 /**
179 * Retrieve user info by a given field
180 * @param string $field The field to retrieve the user with. id | slug | email | login
181 * @param int|string $value A value for $field. A user ID, slug, email address, or login name.
182 * @return WP_User|bool WP_User object on success, false on failure.
183 */
184 function get_user_by( $field, $value ) {
185 $userdata = WP_User::get_data_by( $field, $value );
186
187 if ( !$userdata )
188 return false;
189
190 $user = new WP_User;
191 $user->init( $userdata );
192
193 return $user;
194 }
195 endif;
196
197 if ( !function_exists('is_user_logged_in') ) :
198 /**
199 * Checks if the current visitor is a logged in user.
200 * @return bool True if user is logged in, false if not logged in.
201 */
202 function is_user_logged_in() {
203 if ( ! function_exists( 'wp_set_current_user' ) )
204 return false;
205
206 $user = wp_get_current_user();
207
208 if ( ! $user->exists() )
209 return false;
210
211 return true;
212 }
213 endif;
214
215 /***************************************************************************
216 * Plugin Load Filter
217 **************************************************************************/
218
219 if(in_array( 'plugin-load-filter/plugin-load-filter.php', (array) get_option( 'active_plugins', array() ) )){
220 $plugin_load_filter = new Plf_filter();
221 } elseif ( is_multisite() ) {
222 $plugins = get_site_option( 'active_sitewide_plugins');
223 if ( isset($plugins['plugin-load-filter/plugin-load-filter.php']) ){
224 $plugin_load_filter = new Plf_filter();
225 }
226 }
227
228 class Plf_filter {
229 static private $filter; //Plugin Load Filter Setting option data
230 static private $rlocale;
231 static private $url_filter;
232 static private $s_url_filter;
233 static private $is_filterkey;
234 static private $iniget_active_plugins;
235 static private $iniget_active_sitewide_plugins;
236 static private $base_plugins;
237 static private $filtered_plugins;
238 static private $cache;
239 static private $url2id;
240 static private $pre_post_id;
241 static private $base_public_query_vars;
242
243 function __construct() {
244 self::$rlocale = null;
245 self::$cache = array();
246 self::$url2id = array();
247 self::$pre_post_id = 0;
248 self::$base_public_query_vars = array();
249 self::$url_filter = array();
250 self::$s_url_filter = array();
251 self::$is_filterkey = false;
252 self::$iniget_active_plugins = array();
253 self::$iniget_active_sitewide_plugins = array();
254 self::$base_plugins = array();
255 self::$filtered_plugins = array();
256 self::$filter = get_option('plf_option', array());
257 if(!empty(self::$filter)){
258 //Addon option get
259 self::$iniget_active_plugins = $plugins = get_option( 'active_plugins', array() );
260 if ( is_multisite() ) {
261 self::$iniget_active_sitewide_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
262 $plugins = array_merge( $plugins, array_keys( self::$iniget_active_sitewide_plugins ) );
263 }
264 if(!empty($plugins) && in_array( 'plugin-load-filter-addon/plugin-load-filter-addon.php', $plugins)){
265 self::$url_filter = get_option('plf_addon_options', array());
266 }
267
268 //active_plugins filter
269 if ( is_multisite() ) {
270 add_filter('pre_site_option_active_sitewide_plugins', array('Plf_filter', 'active_sitewide_plugins'));
271 add_action('update_site_option_active_sitewide_plugins', array($this, 'update_active_sitewide_plugins'), 99999, 4);
272 }
273 add_filter('pre_option_active_plugins', array('Plf_filter', 'active_plugins'));
274 add_filter('pre_option_jetpack_active_modules', array('Plf_filter', 'active_jetmodules'));
275 add_filter('pre_option_celtispack_active_modules', array('Plf_filter', 'active_celtismodules'));
276
277 add_filter('plf_singler_custom_url_to_postid', array('Plf_filter', 'custom_url_to_postid'), 10, 3);
278
279 add_action('update_option_active_plugins', array($this, 'update_active_plugins'), 99999, 3);
280 add_action('update_option_jetpack_active_modules', array($this, 'update_active_jetmodules'), 99999, 3);
281 add_action('update_option_celtispack_active_modules', array($this, 'update_active_celtismodules'), 99999, 3);
282 add_action('switch_theme', array($this, 'switch_theme'));
283
284 add_action('plugins_loaded', array($this, 'plugins_loaded'));
285 add_action('admin_init', array($this, 'cache_post_type'));
286 //admin-bar filtered status
287 if(!empty(self::$filter['admin_bar'])){
288 add_action('admin_bar_menu', array($this,'custom_bar_menus'), 201);
289 }
290 //language locale filter
291 if(!empty(self::$filter['language'])){
292 add_filter( 'locale', array('Plf_filter', 'post_locale') );
293 add_filter( 'determine_locale', array('Plf_filter', 'post_determine_locale') );
294 }
295 }
296 }
297
298 //Notice: scriptを使うと AMP でエラーとなるので target でオープン/クローズを行う
299 static function plf_filtered_result_dialog( $text ) {
300 ?>
301 <style>
302 #wpadminbar #wp-admin-bar-plf-statlink .ab-icon:before { content: '\f106'; top: 2px;}
303 #plf-status { display:none;}
304 #plf-status:target { display:block;}
305 #plf-status .dialog-overlay{ position:fixed; left:0px; top:0px; width:100%; height:100%; background-color:rgba(0,0,0,.5); z-index:999999999;}
306 #plf-status div.dialog { position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); width:66%; max-width:420px; height:auto; padding:1.5em; color:#222; background:#fff; z-index:999999999;}
307 #plf-status .dialog-title { margin: 0 0 1em; font-size: 16px;}
308 #plf-status textarea { font-size: 13px;}
309 #plf-status .button-group { display:block; margin-top:2em; text-align:right; font-size:1em;}
310 #plf-status a.button { display:inline-block; text-decoration:none; margin: 0 0 0 1em; padding: .5em 1em; color: #0071a1; background: #f5f5f5; border:solid 1px #0071a1; border-radius:3px; cursor:pointer;}
311 #plf-status a.button:hover { background: #e8ffff; border-color: #016087; color: #016087;}
312 </style>
313 <div id="plf-status">
314 <div class="dialog-overlay"></div>
315 <div class="dialog">
316 <p class="dialog-title"><strong><?php echo 'Plugin Load Filter status'; ?></strong></p>
317 <div><textarea id="plf-filtered-result" style="width:100%; height:320px; margin:5px 0;"><?php echo esc_html($text); ?></textarea></div>
318 <div class="button-group">
319 <a href="#" id="plf-status-close" class="button" aria-label="Close modal">Close</a>
320 </div>
321 </div>
322 </div>
323 <?php
324 }
325
326 //filtered plugins list print
327 static function result_plugin_print( $e_plugins, $d_plugins ) {
328 $text = PHP_EOL . "[Activate Plugins]" . PHP_EOL;
329 $idx = 1;
330 foreach ($e_plugins as $key) {
331 if(!empty($key)){
332 $key = preg_replace('|/.+?\.php|', '', $key);
333 $text .= "$idx. $key" . PHP_EOL;
334 $idx++;
335 }
336 }
337 $text .= PHP_EOL . "[Deactivate Plugins]" . PHP_EOL;
338 $idx = 1;
339 foreach ($d_plugins as $key) {
340 if(!empty($key)){
341 $key = preg_replace('|/.+?\.php|', '', $key);
342 $text .= "$idx. $key" . PHP_EOL;
343 $idx++;
344 }
345 }
346 return $text;
347 }
348
349 public function custom_bar_menus($wp_admin_bar) {
350 if (current_user_can( 'activate_plugins' )) {
351 $base_plugins = self::get_base_plugins();
352 if(!empty($base_plugins)){
353 $text = '==== Plugin Load Filter status ====' . PHP_EOL;
354 $is_filterkey = self::is_filterkey();
355 if($is_filterkey !== false){
356 $text .= '[Filter] ' . $is_filterkey . PHP_EOL;
357 $e_plugins = self::get_filtered_plugins();
358 $d_plugins = array_diff( $base_plugins, $e_plugins );
359 } else {
360 $text .= '[Filter] Not Used' . PHP_EOL;
361 $e_plugins = $base_plugins;
362 $d_plugins = array();
363 }
364 ksort($e_plugins, SORT_STRING);
365 ksort($d_plugins, SORT_STRING);
366
367 $text .= self::result_plugin_print( $e_plugins, $d_plugins );
368 self::plf_filtered_result_dialog( $text );
369 $wp_admin_bar->add_menu( array(
370 'id' => 'plf-statlink',
371 'title' => '<span class="ab-icon"></span>PLF',
372 'href' => '#plf-status',
373 ));
374 }
375 }
376 }
377
378 //active_sitewide plugins Filter add ver2.4.0
379 static function active_sitewide_plugins( $default = false) {
380 return self::plf_filter( 'active_sitewide_plugins', $default);
381 }
382
383 //active plugins Filter
384 static function active_plugins( $default = false) {
385 return self::plf_filter( 'active_plugins', $default);
386 }
387
388 //Jetpack module Filter
389 static function active_jetmodules( $default = false) {
390 return self::plf_filter( 'jetpack_active_modules', $default);
391 }
392
393 //Celtispack module Filter
394 static function active_celtismodules( $default = false) {
395 return self::plf_filter( 'celtispack_active_modules', $default);
396 }
397
398 function updated_plf_stat() {
399 $default = array(
400 'post_type_query_vars' => array(),
401 'queryable_post_types' => array(),
402 //'wp_post_statuses' => array(),
403 //'wp_post_types' => array(),
404 //'wp_taxonomies' => array(),
405 'stat_change' => false,
406 );
407 $data = get_option('plf_queryvars', array());
408 $data = wp_parse_args( (array) $data, $default);
409 //plugin bulk action repeated call
410 if(empty($data['stat_change'])){
411 $data['stat_change'] = true;
412 update_option('plf_queryvars', $data, 'no');
413 }
414 }
415
416 //Plugin/Module activate or deactivate stat change
417 function update_active_sitewide_plugins( $option, $value, $old_value, $network_id ) {
418 $this->updated_plf_stat();
419 }
420 function update_active_plugins( $old_value, $value, $option ) {
421 $this->updated_plf_stat();
422 }
423 function update_active_jetmodules( $old_value, $value, $option ) {
424 $this->updated_plf_stat();
425 }
426 function update_active_celtismodules( $old_value, $value, $option ) {
427 $this->updated_plf_stat();
428 }
429 function switch_theme() {
430 $this->updated_plf_stat();
431 }
432
433 //Make taxonomies and posts available to 'plugin load filter'.
434 //force register_taxonomy (category, post_tag, post_format)
435 static function force_initial_taxonomies(){
436 global $wp_actions;
437 $wp_actions[ 'init' ] = 1;
438 create_initial_taxonomies();
439 create_initial_post_types();
440 unset($wp_actions[ 'init' ]);
441 }
442
443 //all plugins loaded
444 function plugins_loaded() {
445 //ver4.0.5 カスタムポストタイプのキャッシュデータを $wp_post_types グローバル変数には反映しないよう変更したのでこの処理は不要となるが、なんらかの影響があると嫌なのでとりあえず残しておく
446 // woocommerce が init 後に register_post_type, register_taxonomy が実行されたか判定しているので該当データを一旦クリアして init で再登録させる
447 if(post_type_exists( 'product' )){
448 if(method_exists('WC_Post_Types', 'register_post_types')){
449 unregister_post_type( 'product' );
450 //ver4.0.2 wc_register_order_type で登録されるタイプも一旦クリアする
451 if(post_type_exists( 'shop_order' )){
452 unregister_post_type( 'shop_order' );
453 }
454 if(post_type_exists( 'shop_order_refund' )){
455 unregister_post_type( 'shop_order_refund' );
456 }
457 }
458 }
459 if ( taxonomy_exists( 'product_type' ) ) {
460 if(method_exists('WC_Post_Types', 'register_taxonomies')){
461 unregister_taxonomy( 'product_type' );
462 }
463 }
464 }
465
466 //Post Format Type, Custom Post Type Data Cache for parse request
467 function cache_post_type() {
468 if (!is_admin() || self::$is_filterkey !== false || ( defined('DOING_AJAX') && DOING_AJAX ))
469 return;
470
471 $default = array(
472 'post_type_query_vars' => array(),
473 'queryable_post_types' => array(),
474 //'wp_post_statuses' => array(),
475 //'wp_post_types' => array(),
476 //'wp_taxonomies' => array(),
477 'stat_change' => false,
478 );
479 $data = get_option('plf_queryvars', array());
480 $data = wp_parse_args( (array) $data, $default);
481
482 global $plugin_page;
483 if(isset($plugin_page) && $plugin_page === 'plugin_load_filter_admin_manage_page'){
484 $data['stat_change'] = true;
485 }
486
487 //init or plugin activate or deactivate stat change
488 if(!empty($data['stat_change'])){
489 global $wp;
490 $public_query_vars = (!empty($wp->public_query_vars))? $wp->public_query_vars : array();;
491 $post_type_query_vars = array();
492 foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ){
493 if (!empty($t) && $t->query_var )
494 $post_type_query_vars[$t->query_var] = $post_type;
495 }
496 $queryable_post_types = get_post_types( array('publicly_queryable' => true) );
497
498 //global $wp_post_types;
499 //global $wp_post_statuses;
500 //global $wp_taxonomies;
501 //$data['wp_post_types'] = $wp_post_types;
502 //$data['wp_post_statuses'] = $wp_post_statuses;
503 //$data['wp_taxonomies'] = $wp_taxonomies;
504 //$data['public_query_vars'] = $public_query_vars;
505 //ver4.0.11 使わないデータを取り除きオプションデータを縮小化
506 if(!empty($data['rewrite_rules'])){
507 unset($data['rewrite_rules']); //データの残骸があれば使わないので取り除く
508 }
509 if(!empty($data['wp_post_types'])){
510 unset($data['wp_post_types']);
511 }
512 if(!empty($data['wp_post_statuses'])){
513 unset($data['wp_post_statuses']);
514 }
515 if(!empty($data['wp_taxonomies'])){
516 unset($data['wp_taxonomies']);
517 }
518 if(!empty($data['public_query_vars'])){
519 unset($data['public_query_vars']);
520 }
521 $add_query_vars = array_diff( $public_query_vars, self::$base_public_query_vars );
522 $data['add_public_query_vars']= $add_query_vars;
523 $data['post_type_query_vars'] = $post_type_query_vars;
524 $data['queryable_post_types'] = $queryable_post_types;
525 $data['stat_change'] = false;
526 update_option('plf_queryvars', $data, 'no');
527 }
528 }
529
530 /**
531 * Filters the locale for the current request.
532 *
533 * @param string $locale The locale.
534 */
535 static function post_locale( $locale ) {
536 if(empty(self::$rlocale)) {
537 $pid = 0;
538 if(isset($_SERVER['REQUEST_URI'])){
539 $req_uri = plf_sanitize($_SERVER['REQUEST_URI'], 'url');
540 if ( strpos( $req_uri, 'wp-json' ) !== false || preg_match( '/(admin|wc)-ajax/', $req_uri)) {
541 $refurl = wp_get_raw_referer();
542 if(!empty( $refurl )){
543 if(preg_match( '/post=([0-9]+)?/', $refurl, $match )){
544 $pid = (int)$match[1];
545 } elseif(preg_match( '/post_ID=([0-9]+)?/', $refurl, $match )){
546 $pid = (int)$match[1];
547 } else {
548 $pid = (isset(self::$url2id[$refurl]))? self::$url2id[$refurl] : url_to_postid( $refurl );
549 self::$url2id[$refurl] = (int)$pid;
550 }
551 }
552 } elseif ( strpos( $req_uri, 'wp-admin' ) !== false) {
553 if ( isset( $_GET['post'] ) ) {
554 $pid = (int)plf_sanitize($_GET['post']);
555 } elseif ( isset( $_POST['post_ID'] ) ) {
556 $pid = (int)plf_sanitize($_POST['post_ID']);
557 }
558 } else {
559 global $wp_query;
560 if(!empty(self::$pre_post_id)){
561 $pid = self::$pre_post_id;
562 } elseif(!empty($wp_query)){
563 if(!empty($wp_query->post) && !empty($wp_query->post->ID)){
564 $pid = $wp_query->post->ID;
565 } else {
566 $refurl = wp_get_raw_referer();
567 if (!empty( $refurl )) {
568 $pid = (isset(self::$url2id[$refurl]))? self::$url2id[$refurl] : url_to_postid( $refurl );
569 self::$url2id[$refurl] = (int)$pid;
570 }
571 }
572 }
573 }
574 }
575 if(!empty($pid)){
576 $c_locale = get_post_meta( $pid, '_locale', true );
577 if(!empty($c_locale)){
578 self::$rlocale = $c_locale;
579 }
580 }
581 }
582 if(!empty(self::$rlocale)) {
583 $locale = self::$rlocale;
584 }
585 return $locale;
586 }
587
588 static function post_determine_locale( $locale ) {
589 if(!empty(self::$rlocale)) {
590 $locale = self::$rlocale;
591 }
592 return $locale;
593 }
594
595 //This filter hook for when the post ID cannot be detected from the singler URL due to using a permalink change plugin etc.
596 //Permalink Manger plugin (issue from Shawn X.)
597 //Custom Permalinks plugin
598 static function custom_url_to_postid($post_id, $url_path, $pre_active_plugins) {
599 if(empty($post_id) && !empty($pre_active_plugins)){
600 foreach ($pre_active_plugins as $key) {
601 if ( strpos($key, 'permalink-manager' ) !== false){
602 $permalink_manager_uris = (array)get_option('permalink-manager-uris', array());
603 if(empty($permalink_manager_uris)){
604 break;
605 } else {
606 foreach ($permalink_manager_uris as $pid => $slug) {
607 if(preg_match("#/{$slug}(/?$)#ui", $url_path)){
608 $post_id = $pid;
609 break 2;
610 }
611 }
612 }
613 } else if ( strpos($key, 'custom-permalinks' ) !== false){
614 $url = wp_parse_url( get_bloginfo( 'url' ) );
615 $url = isset( $url['path'] ) ? $url['path'] : '';
616 $meta_val = ltrim( substr( $url_path, strlen( $url ) ), '/' );
617
618 global $wpdb;
619 $posts = $wpdb->get_results(
620 $wpdb->prepare(
621 'SELECT p.ID, pm.meta_value, p.post_type, p.post_status ' .
622 " FROM $wpdb->posts AS p INNER JOIN $wpdb->postmeta AS pm ON (pm.post_id = p.ID) " .
623 " WHERE pm.meta_key = 'custom_permalink' " .
624 ' AND (pm.meta_value = %s OR pm.meta_value = %s) ' .
625 " AND p.post_status IN ('publish', 'private', 'inherit') " .
626 " AND p.post_type != 'nav_menu_item' " . // nav_menu_item を除外、他の post_type を許可
627 " ORDER BY FIELD(p.post_status,'publish','private','inherit')," .
628 " p.post_type LIMIT 1",
629 $meta_val,
630 $meta_val . '/'
631 )
632 );
633 if(!empty($posts[0]->ID)) {
634 $post_id = (int)$posts[0]->ID;
635 }
636 break;
637 }
638 }
639 }
640 return $post_id;
641 }
642
643 //プラグインロード前は bbPress等 カスタムポストタイプのデバッグモードでのエラー表示抑制
644 static function exclude_trigger_error( $trigger, $function, $message, $version) {
645 if (did_action( 'plugins_loaded' ) === 0) {
646 if($function === 'map_meta_cap'){
647 $trigger = false;
648 }
649 }
650 return $trigger;
651 }
652 //プラグインロード前は closed 等のカスタムステータスがまだ登録されてない状�
653 �でも取得 posts �
654 報がクリアされないよう抑制
655 static function exclude_map_meta_cap( $caps, $cap, $user_id, $args) {
656 if (did_action( 'plugins_loaded' ) === 0) {
657 if(!empty($caps) && $caps[0] === 'edit_others_posts'){
658 $caps = array();
659 }
660 }
661 return $caps;
662 }
663
664 //parse_request Action Hook for Custom Post Type query add
665 static function parse_request( &$args ) {
666 if (did_action( 'plugins_loaded' ) === 0) {
667 $data = get_option('plf_queryvars', array());
668 if(!empty($data['post_type_query_vars']) && !empty($data['queryable_post_types']) && empty($data['stat_change'])){
669 //ver4.0.5 グローバルのカスタムポストタイプに事前設定するとプラグイン�
670 での登録済みチェック処理とコンフリクトするので止める
671 //global $wp_post_statuses;
672 //global $wp_post_types;
673 //global $wp_taxonomies;
674 //$wp_post_statuses = $data['wp_post_statuses'];
675 //$wp_post_types = $data['wp_post_types'];
676 //$wp_taxonomies = $data['wp_taxonomies'];
677
678 $post_type_query_vars = $data['post_type_query_vars'];
679 $queryable_post_types = $data['queryable_post_types'];
680
681 //query_vars に query_posts() で実行するSQL用のポストタイプデータをセット
682 if(isset($data['add_public_query_vars'])){
683 //ver4.0.11 差分データにしたのでここでマージするが更新時にエラーとならないよう旧処理も残しておく
684 $args->public_query_vars = array_merge(self::$base_public_query_vars, $data['add_public_query_vars']);
685 } else {
686 $args->public_query_vars = $data['public_query_vars'];
687 }
688 if ( isset( $args->matched_query ) ) {
689 parse_str($args->matched_query, $perma_query_vars);
690 }
691
692 foreach ( $args->public_query_vars as $wpvar ) {
693 if ( isset( $args->extra_query_vars[$wpvar] ) ){
694 $args->query_vars[$wpvar] = $args->extra_query_vars[$wpvar];
695 } elseif ( isset( $_GET[ $wpvar ] ) && isset( $_POST[ $wpvar ] ) && $_GET[ $wpvar ] !== $_POST[ $wpvar ] ) {
696 wp_die( 'A variable mismatch has been detected.', 'Sorry, you are not allowed to view this item.', 400 );
697 } elseif ( isset( $_POST[$wpvar] ) ){
698 $args->query_vars[$wpvar] = plf_sanitize($_POST[$wpvar]);
699 } elseif ( isset( $_GET[$wpvar] ) ){
700 $args->query_vars[$wpvar] = plf_sanitize($_GET[$wpvar]);
701 } elseif ( isset( $perma_query_vars[$wpvar] ) ){
702 $args->query_vars[$wpvar] = $perma_query_vars[$wpvar];
703 }
704 if ( !empty( $args->query_vars[$wpvar] ) ) {
705 if ( ! is_array( $args->query_vars[$wpvar] ) ) {
706 $args->query_vars[$wpvar] = (string) $args->query_vars[$wpvar];
707 } else {
708 foreach ( $args->query_vars[$wpvar] as $vkey => $v ) {
709 if ( is_scalar( $v ) ) {
710 $args->query_vars[$wpvar][$vkey] = (string) $v;
711 }
712 }
713 }
714
715 if ( isset($post_type_query_vars[$wpvar] ) ) {
716 $args->query_vars['post_type'] = $post_type_query_vars[$wpvar];
717 $args->query_vars['name'] = $args->query_vars[$wpvar];
718 }
719 }
720 }
721
722 // Limit publicly queried post_types to those that are 'publicly_queryable'.
723 if ( isset( $args->query_vars['post_type']) ) {
724 if ( ! is_array( $args->query_vars['post_type'] ) ) {
725 if ( ! in_array( $args->query_vars['post_type'], $queryable_post_types, true ) ) {
726 unset( $args->query_vars['post_type'] );
727 }
728 } else {
729 $args->query_vars['post_type'] = array_intersect( $args->query_vars['post_type'], $queryable_post_types );
730 }
731 }
732 }
733 }
734 }
735
736 //get filter name
737 static function is_filterkey() {
738 return self::$is_filterkey;
739 }
740 //base plugins (initial activated plugins & module)
741 static function get_base_plugins() {
742 return self::$base_plugins;
743 }
744 //filtered plugins (plugins & module)
745 static function get_filtered_plugins() {
746 return self::$filtered_plugins;
747 }
748
749 /**
750 * Get URL Filter (for addon optional)
751 * @param $stat : 'active' / 'deactive' / '' = all
752 * @param $urltype : 'front' / 'admin' / '' = all
753 * @param $device : 'desktop' / 'mobile' / '' = all
754 * @return url filter data array.
755 */
756 static function get_url_filter( $stat='', $urltype='', $device='' ) {
757 $frontlist = array();
758 $adminlist = array();
759 if(!empty(self::$url_filter)){
760 foreach (self::$url_filter['filter'] as $slug => $v) {
761 if(empty($stat) || (!empty($v['stat']) && $stat === 'active') || (empty($v['stat']) && $stat === 'deactive')){
762 if(empty($device) || (!empty($v['desktop']) && $device === 'desktop') || (!empty($v['mobile']) && $device === 'mobile')){
763 if(!empty($v['type'])){
764 $item = "{$v['group']}-{$v['slug']}";
765 if($v['type'] == 'front'){
766 $frontlist[$item] = $v;
767 } elseif($v['type'] == 'admin'){
768 $adminlist[$item] = $v;
769 }
770 }
771 }
772 }
773 }
774 //group 毎に slug をソート A-Za-z 順となる
775 ksort($frontlist, SORT_STRING);
776 ksort($adminlist, SORT_STRING);
777 }
778 $list = array();
779 if(empty($urltype) || $urltype === 'front'){
780 foreach ($frontlist as $item => $v) {
781 if(!empty($v)){
782 $list[] = $v;
783 }
784 }
785 }
786 if(empty($urltype) || $urltype === 'admin'){
787 foreach ($adminlist as $item => $v) {
788 if(!empty($v)){
789 $list[] = $v;
790 }
791 }
792 }
793 return $list;
794 }
795 //active group list
796 static function get_active_group() {
797 $grouplist = array();
798 $sluglist = self::get_url_filter( 'active' );
799 foreach ($sluglist as $v) {
800 if(!empty($v['group']) && !in_array($v['group'], $grouplist)){
801 $grouplist[] = $v['group'];
802 }
803 }
804 return $grouplist;
805 }
806 //active slug filter data in group
807 static function get_slug_filter( $group ) {
808 $list = array();
809 $sluglist = self::get_url_filter( 'active' );
810 foreach ($sluglist as $v) {
811 if(!empty($v['group']) && $v['group'] == $group){
812 $list[] = $v;
813 }
814 }
815 return $list;
816 }
817
818 //Is there a term in taxonomies
819 static function is_term_in_taxonomy( $post_id, $term, $taxonomies) {
820 $ret = false;
821 $txs = explode(',', $taxonomies);
822 foreach ( $txs as $slug ) {
823 if(!empty($slug)){
824 $names = '';
825 $terms = get_the_terms( $post_id, $slug );
826 if (!empty($terms) ) {
827 foreach ( $terms as $tobj ) {
828 if(!empty($tobj)){
829 $names .= $tobj->name . ',';
830 }
831 }
832 if(strpos($names, $term ) !== false){
833 $ret = true;
834 break;
835 }
836 }
837 }
838 }
839 return $ret;
840 }
841
842 // url path, query parameter match check
843 static function is_url_match( $req_url, $parse_url, $filter ) {
844 if(empty($req_url))
845 return false;
846 if(empty($parse_url['path'])) //url host name only request -> home path(/) set
847 $parse_url['path'] = '/';
848 $_url['url_path'] = $parse_url['path'];
849 $_url['url_q_and'] = $_url['url_q_not'] = (!empty($parse_url['query']))? $parse_url['query'] : '';
850
851 $match = array();
852 $keynum = array();
853 foreach (array('url_path', 'url_q_and', 'url_q_not') as $item) {
854 $match[$item] = 0;
855 $keynum[$item] = 0;
856 if($item === 'url_path'){
857 $reg_before = "(/?)";
858 $reg_after = "(/?$)";
859 } else {
860 $reg_before = "(^|&)";
861 $reg_after = "(=|&|$)";
862 }
863
864 $keylist = (!empty($filter[$item])) ? $filter[$item] : '';
865 $keylist = str_replace( "*", ".+?", $keylist);
866 $ar_key = (!empty($keylist))? array_filter( array_map("trim", explode(PHP_EOL, $keylist))) : array();
867 $keynum[$item] = count($ar_key);
868 if(empty($ar_key)) {
869 if($item === 'url_path')
870 $match[$item] += 1;
871 } else {
872 $ar_new = array();
873 foreach ($ar_key as $key) {
874 //v4.0.6 home (/) のみの指定は別判定しないとトレイルスラッシュで終わる�
875 �てのURLにマッチしてしまう
876 if($item === 'url_path' && $key === '/'){
877 if($_url['url_path'] === '/'){
878 $match[$item] += 1;
879 }
880 } elseif(preg_match("#{$reg_before}{$key}{$reg_after}#ui", $_url[$item])){
881 $match[$item] += 1;
882 }
883 }
884 }
885 }
886 $group = false;
887 $hit = ($match['url_path'] > 0 && $match['url_q_and'] === $keynum['url_q_and'] && $match['url_q_not'] === 0)? true : false;
888 if($hit){
889 if((strpos($_url['url_path'], 'admin-ajax.php' ) !== false || strpos($_url['url_q_and'], 'wc-ajax' ) !== false) && (int)$filter['targetpage'] === 2){
890 $action = '';
891 if(isset($_REQUEST['action'])){
892 $action = plf_sanitize( $_REQUEST['action'] );
893 } elseif(!empty( $_GET['wc-ajax'] )) {
894 $action = plf_sanitize( $_GET['wc-ajax'] );
895 }
896 if(!empty($filter['ajax_action'])){
897 if( $action == $filter['ajax_action'] ){
898 $group = $filter['group'];
899 }
900 } else {
901 //exclude special action : plugin_load_filter, plf_urlfilter_test
902 if (! in_array( $action, array('plugin_load_filter', 'plf_urlfilter_test')) ){
903 $group = $filter['group'];
904 }
905 }
906 } elseif(strpos($_url['url_path'], 'post-new.php' ) === false && (int)$filter['targetpage'] === 1){
907 $post_id = 0;
908 if ( isset( $_GET['post'] ) && isset( $_POST['post_ID'] ) && (int) $_GET['post'] !== (int) $_POST['post_ID'] ) {
909 } elseif ( isset( $_GET['post'] ) ) {
910 $post_id = (int)plf_sanitize($_GET['post']);
911 } elseif ( isset( $_POST['post_ID'] ) ) {
912 $post_id = (int)plf_sanitize($_POST['post_ID']);
913 }
914 if(empty($post_id)){
915 //クエリーパラメータ形式だとポストIDが取得できないようなので、シュミレータ以外なら $wp_query->post->ID を使う
916 global $wp_query;
917 if(!empty($wp_query)){
918 if (isset($_REQUEST['action']) && isset($_POST['test_url']) ) {
919 $post_id = (isset(self::$url2id[$req_url]))? self::$url2id[$req_url] : url_to_postid( $req_url );
920 self::$url2id[$req_url] = (int)$post_id;
921 } else {
922 if(!empty($wp_query->post) && !empty($wp_query->post->ID)){
923 $post_id = $wp_query->post->ID;
924 } else {
925 $post_id = (isset(self::$url2id[$req_url]))? self::$url2id[$req_url] : url_to_postid( $req_url );
926 self::$url2id[$req_url] = (int)$post_id;
927 }
928 }
929 }
930 $post_id = apply_filters('plf_singler_custom_url_to_postid', $post_id, $parse_url['path'], self::$base_plugins);
931 if(!empty($post_id)){
932 if(empty($wp_query->post)){
933 $r = new WP_Query( array( 'p' => $post_id, 'post_type' => 'any' ) );
934 if ($r->have_posts()) {
935 if(!empty($r->post)){
936 $wp_query->posts = $r->posts;
937 $wp_query->post = $r->post;
938 }
939 }
940 }
941 self::$url2id[$req_url] = (int)$post_id;
942 }
943 }
944 if(!empty($post_id)){
945 $post = get_post( $post_id );
946 if ( is_object($post) && !empty($post->post_type)) {
947 if(!empty($filter['post_type'])){
948 if(preg_match("#{$post->post_type}#", $filter['post_type'])){
949 if(!empty($filter['taxonomies']) && !empty($filter['term'])){
950 if(self::is_term_in_taxonomy( $post_id, $filter['term'], $filter['taxonomies'])){
951 $group = $filter['group'];
952 }
953 } else {
954 $group = $filter['group'];
955 }
956 }
957 } else {
958 if(!empty($filter['taxonomies']) && !empty($filter['term'])){
959 if(self::is_term_in_taxonomy( $post_id, $filter['term'], $filter['taxonomies'])){
960 $group = $filter['group'];
961 }
962 } else {
963 $group = $filter['group'];
964 }
965 }
966 }
967 }
968 } else {
969 $group = $filter['group'];
970 }
971 }
972 return($group);
973 }
974
975 static function plugin_keygen( $fname, $option ) {
976 $key = false;
977 if($option === 'jetpack_active_modules'){
978 $key = 'jetpack_module/' . $fname;
979 } elseif($option === 'celtispack_active_modules'){
980 $key = 'celtispack_module/' . str_replace( '.php', '', basename( $fname ) );
981 } else {
982 $key = $fname;
983 }
984 return $key;
985 }
986
987 /**
988 * Get valid plugins list for groupkey (for addon optional)
989 * @param $groupkey : url filter group name
990 * @param $filter : plf filtering setting data
991 * @param $option : option data eg. 'active_plugins', 'active_sitewide_plugins', 'jetpack_active_modules' ...
992 * @param $plugins : active plugins values before filtering
993 * @return data values after filtering
994 */
995 static function filter_to_active_plugins( $groupkey, $filter, $option, $plugins ){
996 $new_plugins = array();
997 foreach ( $plugins as $item ) {
998 if(!empty($item)){
999 $unload = false;
1000 $p_key = self::plugin_keygen( $item, $option );
1001 if(!empty($filter['plfurlkey'][$groupkey]['plugins'])){
1002 if(false !== strpos($filter['plfurlkey'][$groupkey]['plugins'], $p_key))
1003 $unload = true;
1004 }
1005 if(!$unload) {
1006 if($option === 'active_sitewide_plugins'){
1007 // v4.0.6 $new_plugins[$item] = $plugins[$item];
1008 $new_plugins[$item] = $item;
1009 } else {
1010 $new_plugins[] = $item;
1011 }
1012 }
1013 }
1014 }
1015
1016 $new_plugins = apply_filters('plf_custom_changes_to_active_plugins', $new_plugins);
1017 return $new_plugins;
1018 }
1019
1020 /**
1021 * Get valid plugins list for ajax acceleration filter
1022 * @param $p_slugs : ajax _ajax_plf activate plugins slug data (Separate multiple with commas)
1023 * @param $option : option data eg. 'active_plugins', 'active_sitewide_plugins', 'jetpack_active_modules' ...
1024 * @param $plugins : active plugins values before filtering
1025 * @return data values after filtering
1026 */
1027 static function ajaxfilter_to_active_plugins( $p_slugs, $option, $plugins ){
1028 //�
1029 �合用にカンマ区切りをスラッシュ区切りへ変換
1030 $arslugs = array_filter( array_map("trim", explode(',', $p_slugs)));
1031 $slugs = '/' . implode('/', $arslugs) . '/';
1032
1033 $new_plugins = array();
1034 foreach ( $plugins as $item ) {
1035 if(!empty($item)){
1036 $unload = false;
1037 $p_key = self::plugin_keygen( $item, $option );
1038 $sep = strpos($p_key, '/' );
1039 $p_slug = ($sep !== false)? substr($p_key, 0, $sep) : $p_key;
1040 if(false === strpos($slugs, "/$p_slug/")){
1041 $unload = true;
1042 }
1043 if(!$unload) {
1044 if($option === 'active_sitewide_plugins'){
1045 $new_plugins[$item] = $item;
1046 } else {
1047 $new_plugins[] = $item;
1048 }
1049 }
1050 }
1051 }
1052 return $new_plugins;
1053 }
1054
1055 //Plugin Load Filter Main (active plugins/modules filtering)
1056 static function plf_filter( $option, $default = false) {
1057 if ( defined( 'WP_SETUP_CONFIG' ) || did_action( 'mu_plugin_loaded' ) === 0)
1058 return false;
1059
1060 //Check if the caller is wp-settings.php wp_get_active_network_plugins() / wp_get_active_and_valid_plugins()
1061 if( in_array($option, array('active_plugins', 'active_sitewide_plugins' ))){
1062 $is_caller_target = false;
1063 $trace = debug_backtrace();
1064 foreach ($trace as $stp) {
1065 if(isset($stp['file']) && strpos($stp['file'], 'wp-settings.php') !== false){
1066 if(isset($stp['function']) && in_array($stp['function'], array('wp_get_active_network_plugins', 'wp_get_active_and_valid_plugins'))){
1067 $is_caller_target = true;
1068 break;
1069 }
1070 }
1071 }
1072 if( !$is_caller_target ) {
1073 return false;
1074 }
1075 }
1076
1077 if ( ! defined( 'WP_INSTALLING' ) ) {
1078 global $wpdb, $current_site;
1079 if ( is_multisite() && $option === 'active_sitewide_plugins' ) {
1080 //get_network_option() current site ID
1081 $network_id = $current_site->id;
1082
1083 // prevent non-existent options from triggering multiple queries
1084 $notoptions_key = "$network_id:notoptions";
1085 $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
1086 if ( isset( $notoptions[ $option ] ) ) {
1087 return apply_filters( 'default_site_option_' . $option, $default, $option );
1088 }
1089
1090 $cache_key = "$network_id:$option";
1091 $opt_value = wp_cache_get( $cache_key, 'site-options' );
1092
1093 if ( ! isset( $opt_value ) || false === $opt_value ) {
1094 $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
1095
1096 // Has to be get_row instead of get_var because of funkiness with 0, false, null values
1097 if ( is_object( $row ) ) {
1098 $opt_value = $row->meta_value;
1099 $opt_value = maybe_unserialize( $opt_value );
1100 wp_cache_set( $cache_key, $opt_value, 'site-options' );
1101 } else {
1102 if ( ! is_array( $notoptions ) ) {
1103 $notoptions = array();
1104 }
1105 $notoptions[ $option ] = true;
1106 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
1107
1108 /** This filter is documented in wp-includes/option.php */
1109 $opt_value = apply_filters( 'default_site_option_' . $option, $default, $option );
1110 }
1111 }
1112 } else {
1113 // prevent non-existent options from triggering multiple queries
1114 $notoptions = wp_cache_get( 'notoptions', 'options' );
1115 if ( isset( $notoptions[$option] ) )
1116 return apply_filters( 'default_option_' . $option, $default );
1117
1118 $alloptions = wp_load_alloptions();
1119 if ( isset( $alloptions[$option] ) ) {
1120 $opt_value = $alloptions[$option];
1121 } else {
1122 $opt_value = wp_cache_get( $option, 'options' );
1123
1124 if ( false === $opt_value ) {
1125 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
1126
1127 // Has to be get_row instead of get_var because of funkiness with 0, false, null values
1128 if ( is_object( $row ) ) {
1129 $opt_value = $row->option_value;
1130 wp_cache_add( $option, $opt_value, 'options' );
1131 } else { // option does not exist, so we must cache its non-existence
1132 if ( ! is_array( $notoptions ) ) {
1133 $notoptions = array();
1134 }
1135 $notoptions[$option] = true;
1136 wp_cache_set( 'notoptions', $notoptions, 'options' );
1137
1138 /** This filter is documented in wp-includes/option.php */
1139 return apply_filters( 'default_option_' . $option, $default, $option );
1140 }
1141 }
1142 }
1143 }
1144 } else {
1145 return false;
1146 }
1147
1148 $req_url = (isset($_SERVER['REQUEST_URI']))? plf_sanitize($_SERVER['REQUEST_URI'], 'url') : '';
1149 $req_url = str_replace( "\\", "/", $req_url);
1150 $parse_url = parse_url($req_url);
1151 $action = (!empty($parse_url['path']) && strpos($parse_url['path'], 'admin-ajax.php' ) !== false && isset($_REQUEST['action']))? plf_sanitize($_REQUEST['action']) : '';
1152
1153 $act_plugins = ($option === 'active_sitewide_plugins')? array_keys( (array)$opt_value ) : maybe_unserialize( $opt_value );
1154 if($option === 'celtispack_active_modules'){
1155 if(empty(self::$base_plugins['celtispack-addon/celtispack-addon.php'])){
1156 $opt = get_option( 'celtis_addon_options', array() );
1157 if(!empty($opt['active_modules'])){
1158 $nact_plugins = array();
1159 foreach ($act_plugins as $pkey) {
1160 if(!empty($pkey)){
1161 $key = str_replace( '.php', '', basename( $pkey ));
1162 if(!empty($opt['active_modules'][$key]))
1163 continue;
1164 $nact_plugins[] = $pkey;
1165 }
1166 }
1167 $act_plugins = $nact_plugins;
1168 }
1169 }
1170 }
1171
1172 //Equal treatment for when the wp_is_mobile is not yet available(wp-include/vars.php wp_is_mobile)
1173 if ( isset( $_SERVER['HTTP_SEC_CH_UA_MOBILE'] ) ) {
1174 // This is the `Sec-CH-UA-Mobile` user agent client hint HTTP request header.
1175 // See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA-Mobile>.
1176 $is_mobile = ( '?1' === $_SERVER['HTTP_SEC_CH_UA_MOBILE'] );
1177 } elseif ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
1178 $is_mobile = false;
1179 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mobile' ) // Many mobile devices (all iPhone, iPad, etc.)
1180 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Android' )
1181 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Silk/' )
1182 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Kindle' )
1183 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'BlackBerry' )
1184 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera Mini' )
1185 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera Mobi' ) ) {
1186 $is_mobile = true;
1187 } else {
1188 $is_mobile = false;
1189 }
1190 $is_mobile = apply_filters( 'custom_is_mobile' , $is_mobile );
1191
1192 //get_option is called many times, intermediate processing data to cache
1193 $keyid = md5('plf_'. (string)$is_mobile . $req_url . $action);
1194 if(!empty(self::$cache[$keyid][$option])){
1195 return self::$cache[$keyid][$option];
1196 }
1197
1198 //Before plugins loaded, it does not use conditional branch such as is_home, to set wp_query, wp in temporary query
1199 if(empty($GLOBALS['wp_the_query'])){
1200 // プラグイン無効化時等で rewrite_rule がクリアされると rewrite_rule が更新されるまでカスタムポストタイプを判定できずにカスタムポストタイプのページはホームへ飛ばされる
1201 // 但し、permlink structure が plain(基本) の場合は除く
1202 if(!empty(get_option( 'permalink_structure' ))){
1203 $rewrite_rules = get_option('rewrite_rules');
1204 // rewrite_rule を監視して変更された場合はプラグインのフィルタリングをスキップさせていたが、
1205 // plugin activate / deactivate を監視するように変更したのでここでは空の場合のみチェック
1206 if(empty($rewrite_rules)){
1207 return false;
1208 }
1209 // Welcart usces_itemnew 新規商品追加時のエラー (A variable mismatch has been detected.) parse_request で発生してるので特別に回避
1210 if ( isset( $_GET[ 'page' ] ) && isset( $_POST[ 'page' ] ) && $_GET[ 'page' ] !== $_POST[ 'page' ] ) {
1211 return false;
1212 }
1213 }
1214 $GLOBALS['wp_the_query'] = new WP_Query();
1215 $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
1216 $GLOBALS['wp_rewrite'] = new WP_Rewrite();
1217 $GLOBALS['wp'] = new WP();
1218 self::$base_public_query_vars = $GLOBALS['wp']->public_query_vars;
1219 //register_taxonomy(category, post_tag, post_format) support for is_archive
1220 self::force_initial_taxonomies();
1221
1222 if((!empty($parse_url['path']) && (strpos($parse_url['path'], 'admin-ajax.php' ) !== false || strpos($parse_url['path'], '/wp-cron' ) !== false || strpos($parse_url['path'], '/wp-json' ) !== false)) || (!empty($parse_url['query']) && strpos($parse_url['query'], 'rest_route=' ) !== false )){
1223 //ver4.0.15 admin-ajax action:send-attachment-to-editor リクエストが query_posts() 呼び出し時にエラーとなるので ajax, rest api, cron では呼び出さず url filter 処理へ
1224 //https://wordpress.org/support/topic/amin-ajax-php-cant-add-images-in-posts/#post-16938082
1225 } else {
1226 //Post Format, Custom Post Type support
1227 add_action('parse_request', array('Plf_filter', 'parse_request'));
1228 add_filter('doing_it_wrong_trigger_error', array('Plf_filter', 'exclude_trigger_error'), 10, 4 );
1229 //custom parse request filter (for experimental development)
1230 $custom = apply_filters( 'plf_experimental_custom_parse_request', false );
1231 if ( false === $custom) {
1232 $GLOBALS['wp']->parse_request('');
1233 }
1234 $GLOBALS['wp']->query_posts();
1235 }
1236 }
1237
1238 //active plugin data
1239 foreach ($act_plugins as $key) {
1240 if(!empty($key)){
1241 $key = self::plugin_keygen( $key, $option );
1242 self::$base_plugins[$key] = $key;
1243 }
1244 }
1245
1246 $filter = self::$filter;
1247
1248 //plf Addon Extract only target data
1249 $devtype = ($is_mobile)? 'mobile' : 'desktop';
1250 $urltype = (!empty($parse_url['path']) && strpos($parse_url['path'], '/wp-admin' ) !== false)? 'admin' : 'front';
1251 if(!empty(self::$url_filter) && empty(self::$s_url_filter)){
1252 self::$s_url_filter = self::get_url_filter( 'active', $urltype, $devtype );
1253 }
1254
1255
1256 //======== The following are Admin backend page processes ========
1257
1258 if($urltype === 'admin'){
1259 //wp-admin/plugins.php or wp-admin/update-core.php request : Do not filter this request URL
1260 if(strpos($parse_url['path'], '/plugins.php' ) !== false || strpos($parse_url['path'], '/update-core.php' ) !== false){
1261 return false;
1262 }
1263 //Ajax acceleration plugin filter (for plugin developers)
1264 if(!empty($action) && !empty(self::$filter['ajax_accelfilter'])){
1265 $slugs = (isset($_REQUEST['_ajax_plf']))? plf_sanitize($_REQUEST['_ajax_plf']) : '';
1266 if(!empty($slugs)){
1267 $referer = (!empty( $_SERVER['HTTP_REFERER'] )) ? plf_sanitize($_SERVER['HTTP_REFERER'], 'url') : '';
1268 $parse_ref = parse_url($referer);
1269 if(!empty($parse_ref['host']) && strpos( home_url(), $parse_ref['host'] ) !== false){
1270 $new_plugins = self::ajaxfilter_to_active_plugins( $slugs, $option, $act_plugins );
1271 foreach ($new_plugins as $key) {
1272 if(!empty($key)){
1273 $key = self::plugin_keygen( $key, $option );
1274 self::$filtered_plugins[$key] = $key;
1275 }
1276 }
1277 return $new_plugins;
1278 }
1279 }
1280 }
1281 if(!empty(self::$s_url_filter)){
1282 //plf Addon Admin Backend URL filtering
1283 foreach (self::$s_url_filter as $key => $v) {
1284 if(!empty($v)){
1285 $groupkey = self::is_url_match( $req_url, $parse_url, $v );
1286 if($groupkey !== false) {
1287 self::$is_filterkey = 'url-group-filter : ' . $groupkey;
1288 $new_plugins = self::filter_to_active_plugins( $groupkey, $filter, $option, $act_plugins );
1289 self::$cache[$keyid][$option] = $new_plugins;
1290 foreach ($new_plugins as $key) {
1291 if(!empty($key)){
1292 $key = self::plugin_keygen( $key, $option );
1293 self::$filtered_plugins[$key] = $key;
1294 }
1295 }
1296 return $new_plugins;
1297 }
1298 }
1299 }
1300 }
1301 return false;
1302 }
1303
1304
1305 //======== The following are frontend page processes ========
1306
1307 global $wp_query;
1308 $unknown = false;
1309 if( ! is_embed() ){
1310 if((is_home() || is_front_page() || is_archive() || is_search() || is_singular()) == false || (is_home() && !empty($_GET))) {
1311 //bbPress users page requests are treated the same as is_home
1312 //downloadmanager plugin downloadlink request [home]/?wpdmact=XXXXXX exclude home GET query
1313 $unknown = true;
1314
1315 } elseif(is_singular() && empty($wp_query->post)){
1316 //documentroot special php file (wp-login.php, wp-cron.php, etc) これらはこの時点では singular とみなされるが post が設定されていないことで判別
1317 //フィルタリングしたい場合は urlfilter Addon を使用すること
1318 //但し、private (非�
1319 �開)ページ時は post がこの時点ではまだ設定されていないので private でクエリー発行して再確認
1320 if(!empty($parse_url['path']) && strpos( $parse_url['path'], '.php' ) === false && !empty($wp_query->query)) {
1321 //get post for private
1322 $query = $wp_query->query;
1323 $query['post_status'] = 'private';
1324 $r = new WP_Query( $query );
1325 if ($r->have_posts()) {
1326 if(!empty($r->post)){
1327 $wp_query->posts = $r->posts;
1328 $wp_query->post = $r->post;
1329 }
1330 } else {
1331 //カスタムステータスがまだ登録されてない状�
1332 �でも取得 posts �
1333 報がクリアされないよう抑制
1334 add_filter( 'map_meta_cap', array('Plf_filter', 'exclude_map_meta_cap'), 10, 4 );
1335 $query['post_status'] = 'any';
1336 $r = new WP_Query( $query );
1337 if ($r->have_posts()) {
1338 if(!empty($r->post)){
1339 $wp_query->posts = $r->posts;
1340 $wp_query->post = $r->post;
1341 }
1342 }
1343 }
1344 }
1345 if(empty($wp_query->post)){
1346 //パーマリンクをカスタムするプラグイン等により URL から post ID が所得できない場合用のフィルターフック
1347 $post_id = apply_filters('plf_singler_custom_url_to_postid', 0, $parse_url['path'], self::$base_plugins);
1348 if(!empty($post_id)){
1349 $r = new WP_Query( array( 'p' => $post_id, 'post_type' => 'any' ) );
1350 if ($r->have_posts()) {
1351 if(!empty($r->post)){
1352 $wp_query->posts = $r->posts;
1353 $wp_query->post = $r->post;
1354 }
1355 }
1356 }
1357 }
1358 if(empty($wp_query->post)){
1359 $unknown = true;
1360 }
1361 }
1362 }
1363
1364 $single_opt = array();
1365 if(is_singular()){
1366 if(is_object($wp_query->post)){
1367 self::$pre_post_id = $wp_query->post->ID; //for post_locale()
1368 $myfilter = get_post_meta( $wp_query->post->ID, '_plugin_load_filter', true );
1369 $default = array( 'filter' => 'default', 'desktop' => '', 'mobile' => '');
1370 $single_opt = (!empty($myfilter))? $myfilter : $default;
1371 $single_opt = wp_parse_args( $single_opt, $default);
1372 }
1373 }
1374 if(!empty(self::$s_url_filter)){
1375 //Addon frontend URL filtering
1376 //個別フィルター有効なシングラーは URL filtering 無効(個別フィルター優�
1377 �)
1378 if(empty($single_opt) || $single_opt['filter'] === 'default'){
1379 foreach (self::$s_url_filter as $key => $v) {
1380 if(!empty($v)){
1381 $groupkey = self::is_url_match( $req_url, $parse_url, $v );
1382 if($groupkey !== false) {
1383 self::$is_filterkey = 'url-group-filter : ' . $groupkey;
1384 $new_plugins = self::filter_to_active_plugins( $groupkey, $filter, $option, $act_plugins );
1385 self::$cache[$keyid][$option] = $new_plugins;
1386 foreach ($new_plugins as $key) {
1387 if(!empty($key)){
1388 $key = self::plugin_keygen( $key, $option );
1389 self::$filtered_plugins[$key] = $key;
1390 }
1391 }
1392 return $new_plugins;
1393 }
1394 }
1395 }
1396 }
1397 }
1398 if($unknown || empty($parse_url['path']) || strpos($parse_url['path'], '/wp-cron' ) !== false || strpos($parse_url['path'], '/wp-json' ) !== false || (!empty($parse_url['query']) && strpos($parse_url['query'], 'rest_route=' ) !== false )){
1399 //url filter 処理後、REST api, cron, フィルター対象外の不明なリクエストはフィルタリング処理を行わない
1400 return false;
1401 }
1402
1403 //plf standard filtering
1404 $type = false;
1405 if(!empty($filter['_pagefilter']['plugins'])){
1406 if(is_embed()){
1407 $type = 'content-card';
1408 } elseif(is_home() || is_front_page()){
1409 $type = 'home';
1410 } elseif(is_archive()) {
1411 $type = 'archive';
1412 } elseif(is_search()) {
1413 $type = 'search';
1414 } elseif(is_attachment()) {
1415 $type = 'attachment';
1416 } elseif(is_page()) {
1417 $type = 'page';
1418 } elseif(is_single()){ //Post & Custom Post
1419 $type = get_post_type( $wp_query->post);
1420 //bbPress private (非�
1421 �開)ページ時のポストタイプ取得
1422 if($type === false && isset($wp_query->query_vars['post_type'])){
1423 $type = $wp_query->query_vars['post_type'];
1424 }
1425 if($type === 'post'){
1426 $fmt = get_post_format( $wp_query->post);
1427 $type = ($fmt === 'standard' || $fmt == false)? 'post' : "post-$fmt";
1428 }
1429 } else {
1430 $type = 'unknown';
1431 }
1432 self::$is_filterkey = 'page-type-filter : ' . $type;
1433 if(is_singular()){
1434 if(!empty($single_opt) && $single_opt['filter'] === 'include'){
1435 self::$is_filterkey = 'page-type-filter : Single page option';
1436 }
1437 }
1438 } elseif(!empty($filter['_admin']['plugins'])){
1439 //Page Type 未指定時は admin type 除外フィルターのみ
1440 self::$is_filterkey = 'page-type-filter : admin filter';
1441 }
1442
1443 $new_plugins = array();
1444 foreach ( $act_plugins as $item ) {
1445 if(!empty($item)){
1446 $unload = false;
1447 $p_key = self::plugin_keygen( $item, $option );
1448 //admin filter
1449 if(!empty($filter['_admin']['plugins'])){
1450 if(in_array($p_key, array_map("trim", explode(',', $filter['_admin']['plugins'])))){
1451 $unload = true;
1452 }
1453 }
1454 //page filter
1455 if(!$unload){
1456 if(!empty($filter['_pagefilter']['plugins'])){
1457 if(in_array($p_key, array_map("trim", explode(',', $filter['_pagefilter']['plugins'])))){
1458 $unload = true;
1459
1460 //desktop/mobile device disable filter
1461 $dis_dev = true;
1462 if(is_singular() && is_object($wp_query->post)){
1463 if(!empty($single_opt) && $single_opt['filter'] === 'include'){
1464 if(!empty($single_opt[$devtype])){
1465 if(false !== strpos($single_opt[$devtype], $p_key))
1466 $dis_dev = false;
1467 elseif(strpos($p_key, 'jetpack/') !== false && strpos($single_opt[$devtype], 'jetpack_module/') !== false)
1468 $dis_dev = false;
1469 elseif(strpos($p_key, 'celtispack/') !== false && strpos($single_opt[$devtype], 'celtispack_module/') !== false)
1470 $dis_dev = false;
1471 }
1472 }
1473 }
1474 if(empty($single_opt) || $single_opt['filter'] === 'default'){
1475 if(!empty($filter['group'][$devtype]['plugins'])){
1476 if(false !== strpos($filter['group'][$devtype]['plugins'], $p_key))
1477 $dis_dev = false;
1478 elseif(strpos($p_key, 'jetpack/') !== false && strpos($filter['group'][$devtype]['plugins'], 'jetpack_module/') !== false)
1479 $dis_dev = false;
1480 elseif(strpos($p_key, 'celtispack/') !== false && strpos($filter['group'][$devtype]['plugins'], 'celtispack_module/') !== false)
1481 $dis_dev = false;
1482 }
1483 }
1484 if(!$dis_dev){
1485 //oEmbed Content API
1486 if(is_embed()){
1487 if(!empty($type) && !empty($filter['group'][$type]['plugins'])){
1488 if(false !== strpos($filter['group'][$type]['plugins'], $p_key))
1489 $unload = false;
1490 elseif(strpos($p_key, 'jetpack/') !== false && strpos($filter['group'][$type]['plugins'], 'jetpack_module/') !== false)
1491 $unload = false;
1492 elseif(strpos($p_key, 'celtispack/') !== false && strpos($filter['group'][$type]['plugins'], 'celtispack_module/') !== false)
1493 $unload = false;
1494 }
1495 } else {
1496 $pgfopt = false;
1497 if(is_singular()){
1498 if(!empty($single_opt) && $single_opt['filter'] === 'include'){
1499 $pgfopt = true;
1500 if(!empty($single_opt[$devtype])){
1501 if(false !== strpos($single_opt[$devtype], $p_key)){
1502 $unload = false;
1503 } else {
1504 //Enable plugin because plugin module is selected
1505 if(strpos($p_key, 'jetpack/') !== false && strpos($single_opt[$devtype], 'jetpack_module/') !== false)
1506 $unload = false;
1507 elseif(strpos($p_key, 'celtispack/') !== false && strpos($single_opt[$devtype], 'celtispack_module/') !== false)
1508 $unload = false;
1509 }
1510 }
1511 }
1512 }
1513 if($pgfopt === false){
1514 if(!empty($type) && !empty($filter['group'][$type]['plugins'])){
1515 if(in_array($p_key, array_map("trim", explode(',', $filter['group'][$type]['plugins'])))){
1516 $unload = false;
1517 } else {
1518 if(strpos($p_key, 'jetpack/') !== false && strpos($filter['group'][$type]['plugins'], 'jetpack_module/') !== false)
1519 $unload = false;
1520 else if(strpos($p_key, 'celtispack/') !== false && strpos($filter['group'][$type]['plugins'], 'celtispack_module/') !== false)
1521 $unload = false;
1522 }
1523 }
1524 }
1525 }
1526 }
1527 }
1528 }
1529 }
1530 if(!$unload) {
1531 if($option === 'active_sitewide_plugins') {
1532 // v4.0.6 $new_plugins[$item] = $opt_value[$item];
1533 $new_plugins[$item] = $item;
1534 } else {
1535 $new_plugins[] = $item;
1536 }
1537 }
1538 }
1539 }
1540
1541 //https://wordpress.org/support/topic/function-to-retriev-user-before-init-hook-is-fired/
1542 $new_plugins = apply_filters('plf_custom_changes_to_active_plugins', $new_plugins);
1543
1544 self::$cache[$keyid][$option] = $new_plugins;
1545 foreach ($new_plugins as $key) {
1546 if(!empty($key)){
1547 $key = self::plugin_keygen( $key, $option );
1548 self::$filtered_plugins[$key] = $key;
1549 }
1550 }
1551 return $new_plugins;
1552 }
1553 }
1554