PluginProbe
Plugin Load Filter / 4.0.6
Plugin Load Filter v4.0.6
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.0.6, at mu-plugins/plf-filter.php

1,123 lines 53.7 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.0.6
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 if ( !function_exists('wp_get_current_user') ) :
18 /**
19 * Retrieve the current user object.
20 * @return WP_User Current user WP_User object
21 */
22 function wp_get_current_user() {
23 if ( ! function_exists( 'wp_set_current_user' ) ){
24 return 0;
25 } else {
26 return _wp_get_current_user();
27 }
28 }
29 endif;
30
31 if ( !function_exists('get_userdata') ) :
32 /**
33 * Retrieve user info by user ID.
34 * @param int $user_id User ID
35 * @return WP_User|bool WP_User object on success, false on failure.
36 */
37 function get_userdata( $user_id ) {
38 return get_user_by( 'id', $user_id );
39 }
40 endif;
41
42 if ( !function_exists('get_user_by') ) :
43 /**
44 * Retrieve user info by a given field
45 * @param string $field The field to retrieve the user with. id | slug | email | login
46 * @param int|string $value A value for $field. A user ID, slug, email address, or login name.
47 * @return WP_User|bool WP_User object on success, false on failure.
48 */
49 function get_user_by( $field, $value ) {
50 $userdata = WP_User::get_data_by( $field, $value );
51
52 if ( !$userdata )
53 return false;
54
55 $user = new WP_User;
56 $user->init( $userdata );
57
58 return $user;
59 }
60 endif;
61
62 if ( !function_exists('is_user_logged_in') ) :
63 /**
64 * Checks if the current visitor is a logged in user.
65 * @return bool True if user is logged in, false if not logged in.
66 */
67 function is_user_logged_in() {
68 if ( ! function_exists( 'wp_set_current_user' ) )
69 return false;
70
71 $user = wp_get_current_user();
72
73 if ( ! $user->exists() )
74 return false;
75
76 return true;
77 }
78 endif;
79
80 /***************************************************************************
81 * Plugin Load Filter
82 **************************************************************************/
83
84 if(in_array( 'plugin-load-filter/plugin-load-filter.php', (array) get_option( 'active_plugins', array() ) )){
85 $plugin_load_filter = new Plf_filter();
86 } elseif ( is_multisite() ) {
87 $plugins = get_site_option( 'active_sitewide_plugins');
88 if ( isset($plugins['plugin-load-filter/plugin-load-filter.php']) ){
89 $plugin_load_filter = new Plf_filter();
90 }
91 }
92
93 class Plf_filter {
94 static private $filter; //Plugin Load Filter Setting option data
95 static private $rlocale;
96 static private $url_filter;
97 static private $s_url_filter;
98 static private $is_filterkey;
99 static private $base_plugins;
100 static private $filtered_plugins;
101 static private $cache;
102 static private $url2id;
103
104 function __construct() {
105 self::$cache = null;
106 self::$url2id = null;
107 self::$rlocale = null;
108 self::$url_filter = null;
109 self::$s_url_filter = null;
110 self::$is_filterkey = false;
111 self::$base_plugins = array();
112 self::$filtered_plugins = array();
113 self::$filter = get_option('plf_option');
114 if(!empty(self::$filter)){
115 //Addon option get
116 $plugins = get_option( 'active_plugins', array() );
117 if ( ! is_array( $plugins ) ) {
118 $plugins = array();
119 }
120 if ( is_multisite() ) {
121 $network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
122 $plugins = array_merge( $plugins, array_keys( $network_plugins ) );
123 }
124 if(in_array( 'plugin-load-filter-addon/plugin-load-filter-addon.php', $plugins)){
125 self::$url_filter = get_option('plf_addon_options');
126 }
127
128 //active_plugins filter
129 if ( is_multisite() ) {
130 add_filter('pre_site_option_active_sitewide_plugins', array('Plf_filter', 'active_sitewide_plugins'));
131 add_action('update_site_option_active_sitewide_plugins', array(&$this, 'update_active_sitewide_plugins'), 99999, 4);
132 }
133 add_filter('pre_option_active_plugins', array('Plf_filter', 'active_plugins'));
134 add_filter('pre_option_jetpack_active_modules', array('Plf_filter', 'active_jetmodules'));
135 add_filter('pre_option_celtispack_active_modules', array('Plf_filter', 'active_celtismodules'));
136
137 add_action('update_option_active_plugins', array(&$this, 'update_active_plugins'), 99999, 3);
138 add_action('update_option_jetpack_active_modules', array(&$this, 'update_jetmodules'), 99999, 3);
139 add_action('update_option_celtispack_active_modules', array(&$this, 'update_celtismodules'), 99999, 3);
140 add_action('switch_theme', array(&$this, 'switch_theme'));
141
142 add_action('plugins_loaded', array(&$this, 'plugins_loaded'));
143 add_action('wp_loaded', array(&$this, 'cache_post_type'), 1);
144 //admin-bar filtered status
145 if(!empty(self::$filter['admin_bar'])){
146 add_action('admin_bar_menu', array(&$this,'custom_bar_menus'), 201);
147 }
148 //language locale filter
149 if(!empty(self::$filter['language'])){
150 add_filter( 'locale', array('Plf_filter', 'post_locale') );
151 add_filter( 'determine_locale', array('Plf_filter', 'post_determine_locale') );
152 }
153 }
154 }
155
156 //Notice: scriptを使うと AMP でエラーとなるので target でオープン/クローズを行う
157 static function plf_filtered_result_dialog( $text ) {
158 ?>
159 <style>
160 #wpadminbar #wp-admin-bar-plf-statlink .ab-icon:before { content: '\f106'; top: 2px;}
161 #plf-status { display:none;}
162 #plf-status:target { display:block;}
163 #plf-status .dialog-overlay{ position:fixed; left:0px; top:0px; width:100%; height:100%; background-color:rgba(0,0,0,.5); z-index:999999999;}
164 #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;}
165 #plf-status .dialog-title { margin: 0 0 1em; font-size: 16px;}
166 #plf-status textarea { font-size: 13px;}
167 #plf-status .button-group { display:block; margin-top:2em; text-align:right; font-size:1em;}
168 #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;}
169 #plf-status a.button:hover { background: #e8ffff; border-color: #016087; color: #016087;}
170 </style>
171 <div id="plf-status">
172 <div class="dialog-overlay"></div>
173 <div class="dialog">
174 <p class="dialog-title"><strong><?php echo 'Plugin Load Filter status'; ?></strong></p>
175 <div><textarea id="plf-filtered-result" style="width:100%; height:320px; margin:5px 0;"><?php echo $text; ?></textarea></div>
176 <div class="button-group">
177 <a href="#" id="plf-status-close" class="button" aria-label="Close modal"><?php _e('Close'); ?></a>
178 </div>
179 </div>
180 </div>
181 <?php
182 }
183
184 //filtered plugins list print
185 static function result_plugin_print( $e_plugins, $d_plugins ) {
186 $text = PHP_EOL . "[Activate Plugins]" . PHP_EOL;
187 $idx = 1;
188 foreach ($e_plugins as $key) {
189 $key = preg_replace('|/.+?\.php|', '', $key);
190 $text .= "$idx. $key" . PHP_EOL;
191 $idx++;
192 }
193 $text .= PHP_EOL . "[Deactivate Plugins]" . PHP_EOL;
194 $idx = 1;
195 foreach ($d_plugins as $key) {
196 $key = preg_replace('|/.+?\.php|', '', $key);
197 $text .= "$idx. $key" . PHP_EOL;
198 $idx++;
199 }
200 return $text;
201 }
202
203 public function custom_bar_menus($wp_admin_bar) {
204 if (current_user_can( 'activate_plugins' )) {
205 $base_plugins = self::get_base_plugins();
206 if(!empty($base_plugins)){
207 $text = '==== Plugin Load Filter status ====' . PHP_EOL;
208 $is_filterkey = self::is_filterkey();
209 if($is_filterkey !== false){
210 $text .= '[Filter] ' . $is_filterkey . PHP_EOL;
211 $e_plugins = self::get_filtered_plugins();
212 $d_plugins = array_diff( $base_plugins, $e_plugins );
213 } else {
214 $text .= '[Filter] Not Used' . PHP_EOL;
215 $e_plugins = $base_plugins;
216 $d_plugins = array();
217 }
218 ksort($e_plugins, SORT_STRING);
219 ksort($d_plugins, SORT_STRING);
220
221 $text .= self::result_plugin_print( $e_plugins, $d_plugins );
222 self::plf_filtered_result_dialog( $text );
223 $wp_admin_bar->add_menu( array(
224 'id' => 'plf-statlink',
225 'title' => '<span class="ab-icon"></span>PLF',
226 'href' => '#plf-status',
227 ));
228 }
229 }
230 }
231
232 //active_sitewide plugins Filter add ver2.4.0
233 static function active_sitewide_plugins( $default = false) {
234 return self::plf_filter( 'active_sitewide_plugins', $default);
235 }
236
237 //active plugins Filter
238 static function active_plugins( $default = false) {
239 return self::plf_filter( 'active_plugins', $default);
240 }
241
242 //Jetpack module Filter
243 static function active_jetmodules( $default = false) {
244 return self::plf_filter( 'jetpack_active_modules', $default);
245 }
246
247 //Celtispack module Filter
248 static function active_celtismodules( $default = false) {
249 return self::plf_filter( 'celtispack_active_modules', $default);
250 }
251
252 function updated_plf_stat() {
253 $default = array(
254 'post_type_query_vars' => array(),
255 'queryable_post_types' => array(),
256 'wp_post_statuses' => array(),
257 'wp_post_types' => array(),
258 'wp_taxonomies' => array(),
259 'stat_change' => false,
260 );
261 $data = get_option('plf_queryvars');
262 $data = wp_parse_args( (array) $data, $default);
263 //plugin bulk action repeated call
264 if(empty($data['stat_change'])){
265 $data['stat_change'] = true;
266 update_option('plf_queryvars', $data);
267 }
268 }
269
270 //Plugin/Module activate or deactivate stat change
271 function update_active_sitewide_plugins( $option, $value, $old_value, $network_id ) {
272 $this->updated_plf_stat();
273 }
274 function update_active_plugins( $old_value, $value, $option ) {
275 $this->updated_plf_stat();
276 }
277 function update_active_jetmodules( $old_value, $value, $option ) {
278 $this->updated_plf_stat();
279 }
280 function update_active_celtismodules( $old_value, $value, $option ) {
281 $this->updated_plf_stat();
282 }
283 function switch_theme() {
284 $this->updated_plf_stat();
285 }
286
287 //Make taxonomies and posts available to 'plugin load filter'.
288 //force register_taxonomy (category, post_tag, post_format)
289 static function force_initial_taxonomies(){
290 global $wp_actions;
291 $wp_actions[ 'init' ] = 1;
292 create_initial_taxonomies();
293 create_initial_post_types();
294 unset($wp_actions[ 'init' ]);
295 }
296
297 //all plugins loaded
298 function plugins_loaded() {
299 //ver4.0.5 カスタムポストタイプのキャッシュデータを $wp_post_types グローバル変数には反映しないよう変更したのでこの処理は不要となるが、なんらかの影響があると嫌なのでとりあえず残しておく
300 // woocommerce が init 後に register_post_type, register_taxonomy が実行されたか判定しているので該当データを一旦クリアして init で再登録させる
301 if(post_type_exists( 'product' )){
302 if(method_exists('WC_Post_Types', 'register_post_types')){
303 unregister_post_type( 'product' );
304 //ver4.0.2 wc_register_order_type で登録されるタイプも一旦クリアする
305 if(post_type_exists( 'shop_order' )){
306 unregister_post_type( 'shop_order' );
307 }
308 if(post_type_exists( 'shop_order_refund' )){
309 unregister_post_type( 'shop_order_refund' );
310 }
311 }
312 }
313 if ( taxonomy_exists( 'product_type' ) ) {
314 if(method_exists('WC_Post_Types', 'register_taxonomies')){
315 unregister_taxonomy( 'product_type' );
316 }
317 }
318 }
319
320 //Post Format Type, Custom Post Type Data Cache for parse request
321 function cache_post_type() {
322 if (!is_admin() || self::$is_filterkey !== false || ( defined('DOING_AJAX') && DOING_AJAX ))
323 return;
324
325 $default = array(
326 'post_type_query_vars' => array(),
327 'queryable_post_types' => array(),
328 'wp_post_statuses' => array(),
329 'wp_post_types' => array(),
330 'wp_taxonomies' => array(),
331 'stat_change' => false,
332 );
333 $data = get_option('plf_queryvars');
334 $data = wp_parse_args( (array) $data, $default);
335
336 //init or plugin activate or deactivate stat change
337 if(empty($data['wp_post_types']) || !empty($data['stat_change'])){
338 global $wp;
339 global $wp_post_types;
340 global $wp_post_statuses;
341 global $wp_taxonomies;
342 $public_query_vars = (!empty($wp->public_query_vars))? $wp->public_query_vars : array();;
343 $post_type_query_vars = array();
344 foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ){
345 if ( $t->query_var )
346 $post_type_query_vars[$t->query_var] = $post_type;
347 }
348 $queryable_post_types = get_post_types( array('publicly_queryable' => true) );
349
350 $data['public_query_vars'] = $public_query_vars;
351 $data['post_type_query_vars'] = $post_type_query_vars;
352 $data['queryable_post_types'] = $queryable_post_types;
353 $data['wp_post_statuses'] = $wp_post_statuses;
354 $data['wp_post_types'] = $wp_post_types;
355 $data['wp_taxonomies'] = $wp_taxonomies;
356 $data['stat_change'] = false;
357 update_option('plf_queryvars', $data);
358 }
359 }
360
361 /**
362 * Filters the locale for the current request.
363 *
364 * @param string $locale The locale.
365 */
366 static function post_locale( $locale ) {
367 if(empty(self::$rlocale)) {
368 $pid = 0;
369 if ( strpos( $_SERVER['REQUEST_URI'], 'wp-json' ) !== false || preg_match( '/(admin|wc)-ajax/', $_SERVER['REQUEST_URI'])) {
370 $refurl = wp_get_raw_referer();
371 if(!empty( $refurl )){
372 if(preg_match( '/post=([0-9]+)?/', $refurl, $match )){
373 $pid = (int)$match[1];
374 } elseif(preg_match( '/post_ID=([0-9]+)?/', $refurl, $match )){
375 $pid = (int)$match[1];
376 } else {
377 $pid = (isset(self::$url2id[$refurl]))? self::$url2id[$refurl] : url_to_postid( $refurl );
378 self::$url2id[$refurl] = (int)$pid;
379 }
380 }
381 } elseif ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false) {
382 if ( isset( $_GET['post'] ) ) {
383 $pid = (int) $_GET['post'];
384 } elseif ( isset( $_POST['post_ID'] ) ) {
385 $pid = (int) $_POST['post_ID'];
386 }
387 } else {
388 global $wp_query;
389 if(is_singular() && is_object($wp_query->post) && !empty($wp_query->post->ID)){
390 $pid = $wp_query->post->ID;
391 } else {
392 $refurl = wp_get_raw_referer();
393 if (!empty( $refurl )) {
394 $pid = (isset(self::$url2id[$refurl]))? self::$url2id[$refurl] : url_to_postid( $refurl );
395 self::$url2id[$refurl] = (int)$pid;
396 }
397 }
398 }
399 if(!empty($pid)){
400 $c_locale = get_post_meta( $pid, '_locale', true );
401 if(!empty($c_locale)){
402 self::$rlocale = $c_locale;
403 }
404 }
405 }
406 if(!empty(self::$rlocale)) {
407 $locale = self::$rlocale;
408 }
409 return $locale;
410 }
411
412 static function post_determine_locale( $locale ) {
413 if(!empty(self::$rlocale)) {
414 $locale = self::$rlocale;
415 }
416 return $locale;
417 }
418
419 //parse_request Action Hook for Custom Post Type query add
420 static function parse_request( &$args ) {
421 if (did_action( 'plugins_loaded' ) === 0) {
422 $data = get_option('plf_queryvars');
423 if(!empty($data['post_type_query_vars']) && !empty($data['queryable_post_types']) && empty($data['stat_change'])){
424 //ver4.0.5 グローバルのカスタムポストタイプに事前設定するとプラグイン�
425 での登録済みチェック処理とコンフリクトするので止める
426 //global $wp_post_statuses;
427 //global $wp_post_types;
428 //global $wp_taxonomies;
429 //$wp_post_statuses = $data['wp_post_statuses'];
430 //$wp_post_types = $data['wp_post_types'];
431 //$wp_taxonomies = $data['wp_taxonomies'];
432 $post_type_query_vars = $data['post_type_query_vars'];
433 $queryable_post_types = $data['queryable_post_types'];
434
435 //query_vars に query_posts() で実行するSQL用のポストタイプデータをセット
436 $args->public_query_vars = $data['public_query_vars'];
437 if ( isset( $args->matched_query ) ) {
438 parse_str($args->matched_query, $perma_query_vars);
439 }
440 foreach ( $args->public_query_vars as $wpvar ) {
441 if ( isset( $args->extra_query_vars[$wpvar] ) )
442 $args->query_vars[$wpvar] = $args->extra_query_vars[$wpvar];
443 elseif ( isset( $_POST[$wpvar] ) )
444 $args->query_vars[$wpvar] = $_POST[$wpvar];
445 elseif ( isset( $_GET[$wpvar] ) )
446 $args->query_vars[$wpvar] = $_GET[$wpvar];
447 elseif ( isset( $perma_query_vars[$wpvar] ) )
448 $args->query_vars[$wpvar] = $perma_query_vars[$wpvar];
449
450 if ( !empty( $args->query_vars[$wpvar] ) ) {
451 if ( ! is_array( $args->query_vars[$wpvar] ) ) {
452 $args->query_vars[$wpvar] = (string) $args->query_vars[$wpvar];
453 } else {
454 foreach ( $args->query_vars[$wpvar] as $vkey => $v ) {
455 if ( !is_object( $v ) ) {
456 $args->query_vars[$wpvar][$vkey] = (string) $v;
457 }
458 }
459 }
460 if ( isset($post_type_query_vars[$wpvar] ) ) {
461 $args->query_vars['post_type'] = $post_type_query_vars[$wpvar];
462 $args->query_vars['name'] = $args->query_vars[$wpvar];
463 }
464 }
465 }
466
467 // Limit publicly queried post_types to those that are publicly_queryable
468 if ( isset( $args->query_vars['post_type']) ) {
469 if ( ! is_array( $args->query_vars['post_type'] ) ) {
470 if ( ! in_array( $args->query_vars['post_type'], $queryable_post_types ) )
471 unset( $args->query_vars['post_type'] );
472 } else {
473 $args->query_vars['post_type'] = array_intersect( $args->query_vars['post_type'], $queryable_post_types );
474 }
475 }
476 }
477 }
478 }
479
480 //get filter name
481 static function is_filterkey() {
482 return self::$is_filterkey;
483 }
484 //base plugins (initial activated plugins & module)
485 static function get_base_plugins() {
486 return self::$base_plugins;
487 }
488 //filtered plugins (plugins & module)
489 static function get_filtered_plugins() {
490 return self::$filtered_plugins;
491 }
492
493 /**
494 * Get URL Filter (for addon optional)
495 * @param $stat : 'active' / 'deactive' / '' = all
496 * @param $urltype : 'front' / 'admin' / '' = all
497 * @param $device : 'desktop' / 'mobile' / '' = all
498 * @return url filter data array.
499 */
500 static function get_url_filter( $stat='', $urltype='', $device='' ) {
501 $frontlist = array();
502 $adminlist = array();
503 if(!empty(self::$url_filter)){
504 foreach (self::$url_filter['filter'] as $slug => $v) {
505 if(empty($stat) || (!empty($v['stat']) && $stat === 'active') || (empty($v['stat']) && $stat === 'deactive')){
506 if(empty($device) || (!empty($v['desktop']) && $device === 'desktop') || (!empty($v['mobile']) && $device === 'mobile')){
507 if(!empty($v['type'])){
508 $item = "{$v['group']}-{$v['slug']}";
509 if($v['type'] == 'front'){
510 $frontlist[$item] = $v;
511 } elseif($v['type'] == 'admin'){
512 $adminlist[$item] = $v;
513 }
514 }
515 }
516 }
517 }
518 //group 毎に slug をソート A-Za-z 順となる
519 ksort($frontlist, SORT_STRING);
520 ksort($adminlist, SORT_STRING);
521 }
522 $list = array();
523 if(empty($urltype) || $urltype === 'front'){
524 foreach ($frontlist as $item => $v) {
525 $list[] = $v;
526 }
527 }
528 if(empty($urltype) || $urltype === 'admin'){
529 foreach ($adminlist as $item => $v) {
530 $list[] = $v;
531 }
532 }
533 return $list;
534 }
535 //active group list
536 static function get_active_group() {
537 $grouplist = array();
538 $sluglist = self::get_url_filter( 'active' );
539 foreach ($sluglist as $v) {
540 if(!in_array($v['group'], $grouplist)){
541 $grouplist[] = $v['group'];
542 }
543 }
544 return $grouplist;
545 }
546 //active slug filter data in group
547 static function get_slug_filter( $group ) {
548 $list = array();
549 $sluglist = self::get_url_filter( 'active' );
550 foreach ($sluglist as $v) {
551 if($v['group'] == $group){
552 $list[] = $v;
553 }
554 }
555 return $list;
556 }
557
558 //Is there a term in taxonomies
559 static function is_term_in_taxonomy( $post_id, $term, $taxonomies) {
560 $ret = false;
561 $txs = explode(',', $taxonomies);
562 foreach ( $txs as $slug ) {
563 $names = '';
564 $terms = get_the_terms( $post_id, $slug );
565 if (!empty($terms) ) {
566 foreach ( $terms as $tobj ) {
567 $names .= $tobj->name . ',';
568 }
569 if(strpos($names, $term ) !== false){
570 $ret = true;
571 break;
572 }
573 }
574 }
575 return $ret;
576 }
577
578 // url path, query parameter match check
579 static function is_url_match( $req_url, $parse_url, $filter ) {
580 if(empty($parse_url['path']))
581 return false;
582 $_url['url_path'] = $parse_url['path'];
583 $_url['url_q_and'] = $_url['url_q_not'] = (!empty($parse_url['query']))? $parse_url['query'] : '';
584
585 $match = array();
586 $keynum = array();
587 foreach (array('url_path', 'url_q_and', 'url_q_not') as $item) {
588 $match[$item] = 0;
589 $keynum[$item] = 0;
590 if($item === 'url_path'){
591 $reg_before = "(/?)";
592 $reg_after = "(/?$)";
593 } else {
594 $reg_before = "(^|&)";
595 $reg_after = "(=|&|$)";
596 }
597
598 $keylist = (!empty($filter[$item])) ? $filter[$item] : '';
599 $keylist = str_replace( "*", ".+?", $keylist);
600 $ar_key = (!empty($keylist))? array_filter( array_map("trim", explode(PHP_EOL, $keylist))) : array();
601 $keynum[$item] = count($ar_key);
602 if(empty($ar_key)) {
603 if($item === 'url_path')
604 $match[$item] += 1;
605 } else {
606 $ar_new = array();
607 foreach ($ar_key as $key) {
608 //v4.0.6 home (/) のみの指定は別判定しないとトレイルスラッシュで終わる�
609 �てのURLにマッチしてしまう
610 if($item === 'url_path' && $key === '/'){
611 if($_url['url_path'] === '/'){
612 $match[$item] += 1;
613 }
614 } elseif(preg_match("#{$reg_before}{$key}{$reg_after}#ui", $_url[$item])){
615 $match[$item] += 1;
616 }
617 }
618 }
619 }
620 $group = false;
621 $hit = ($match['url_path'] > 0 && $match['url_q_and'] === $keynum['url_q_and'] && $match['url_q_not'] === 0)? true : false;
622 if($hit){
623 if((strpos($_url['url_path'], 'admin-ajax.php' ) !== false || strpos($_url['url_q_and'], 'wc-ajax' ) !== false) && (int)$filter['targetpage'] === 2){
624 $action = '';
625 if(isset($_REQUEST['action'])){
626 $action = esc_attr($_REQUEST['action']);
627 } elseif(!empty( $_GET['wc-ajax'] )) {
628 $action = sanitize_text_field( wp_unslash( $_GET['wc-ajax'] ) );
629 }
630 if(!empty($filter['ajax_action'])){
631 if( $action == $filter['ajax_action'] ){
632 $group = $filter['group'];
633 }
634 } else {
635 //exclude special action : plugin_load_filter, plf_urlfilter_test
636 if (! in_array( $action, array('plugin_load_filter', 'plf_urlfilter_test')) ){
637 $group = $filter['group'];
638 }
639 }
640 } elseif(strpos($_url['url_path'], 'post-new.php' ) === false && (int)$filter['targetpage'] === 1){
641 $post_id = 0;
642 if ( isset( $_GET['post'] ) && isset( $_POST['post_ID'] ) && (int) $_GET['post'] !== (int) $_POST['post_ID'] ) {
643 } elseif ( isset( $_GET['post'] ) ) {
644 $post_id = (int) $_GET['post'];
645 } elseif ( isset( $_POST['post_ID'] ) ) {
646 $post_id = (int) $_POST['post_ID'];
647 }
648 if(empty($post_id)){
649 //クエリーパラメータ形式だとポストIDが取得できないようなので、シュミレータ以外なら $wp_query->post->ID を使う
650 if (isset($_REQUEST['action']) && isset($_POST['test_url']) ) {
651 $post_id = (isset(self::$url2id[$req_url]))? self::$url2id[$req_url] : url_to_postid( $req_url );
652 self::$url2id[$req_url] = (int)$post_id;
653 } else {
654 global $wp_query;
655 if(is_object($wp_query->post) && !empty($wp_query->post->ID)) {
656 $post_id = $wp_query->post->ID;
657 } else {
658 $post_id = (isset(self::$url2id[$req_url]))? self::$url2id[$req_url] : url_to_postid( $req_url );
659 self::$url2id[$req_url] = (int)$post_id;
660 }
661 }
662 }
663 if(!empty($post_id)){
664 $post = get_post( $post_id );
665 if ( is_object($post) && !empty($post->post_type)) {
666 if(!empty($filter['post_type'])){
667 if(preg_match("#{$post->post_type}#", $filter['post_type'])){
668 if(!empty($filter['taxonomies']) && !empty($filter['term'])){
669 if(self::is_term_in_taxonomy( $post_id, $filter['term'], $filter['taxonomies'])){
670 $group = $filter['group'];
671 }
672 } else {
673 $group = $filter['group'];
674 }
675 }
676 } else {
677 if(!empty($filter['taxonomies']) && !empty($filter['term'])){
678 if(self::is_term_in_taxonomy( $post_id, $filter['term'], $filter['taxonomies'])){
679 $group = $filter['group'];
680 }
681 } else {
682 $group = $filter['group'];
683 }
684 }
685 }
686 }
687 } else {
688 $group = $filter['group'];
689 }
690 }
691 return($group);
692 }
693
694 static function plugin_keygen( $fname, $option ) {
695 $key = false;
696 if($option === 'jetpack_active_modules'){
697 $key = 'jetpack_module/' . $fname;
698 } elseif($option === 'celtispack_active_modules'){
699 $key = 'celtispack_module/' . str_replace( '.php', '', basename( $fname ) );
700 } else {
701 $key = $fname;
702 }
703 return $key;
704 }
705
706 /**
707 * Get valid plugins list for groupkey (for addon optional)
708 * @param $groupkey : url filter group name
709 * @param $filter : plf filtering setting data
710 * @param $option : option data eg. 'active_plugins', 'active_sitewide_plugins', 'jetpack_active_modules' ...
711 * @param $plugins : active plugins values before filtering
712 * @return data values after filtering
713 */
714 static function filter_to_active_plugins( $groupkey, $filter, $option, $plugins ){
715 $new_plugins = array();
716 foreach ( $plugins as $item ) {
717 $unload = false;
718 $p_key = self::plugin_keygen( $item, $option );
719 if(!empty($filter['plfurlkey'][$groupkey]['plugins'])){
720 if(false !== strpos($filter['plfurlkey'][$groupkey]['plugins'], $p_key))
721 $unload = true;
722 }
723 if(!$unload) {
724 if($option === 'active_sitewide_plugins'){
725 // v4.0.6 $new_plugins[$item] = $plugins[$item];
726 $new_plugins[$item] = $item;
727 } else {
728 $new_plugins[] = $item;
729 }
730 }
731 }
732 return $new_plugins;
733 }
734
735 //Plugin Load Filter Main (active plugins/modules filtering)
736 static function plf_filter( $option, $default = false) {
737 // v4.0.6 if ( defined( 'WP_SETUP_CONFIG' ) || did_action( 'muplugins_loaded' ) === 0)
738 if ( defined( 'WP_SETUP_CONFIG' ) || did_action( 'mu_plugin_loaded' ) === 0)
739 return false;
740
741 if ( ! defined( 'WP_INSTALLING' ) ) {
742 global $wpdb, $current_site;
743 if ( is_multisite() && $option === 'active_sitewide_plugins' ) {
744 //get_network_option() current site ID
745 $network_id = $current_site->id;
746
747 // prevent non-existent options from triggering multiple queries
748 $notoptions_key = "$network_id:notoptions";
749 $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
750 if ( isset( $notoptions[ $option ] ) ) {
751 return apply_filters( 'default_site_option_' . $option, $default, $option );
752 }
753
754 $cache_key = "$network_id:$option";
755 $opt_value = wp_cache_get( $cache_key, 'site-options' );
756
757 if ( ! isset( $opt_value ) || false === $opt_value ) {
758 $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
759
760 // Has to be get_row instead of get_var because of funkiness with 0, false, null values
761 if ( is_object( $row ) ) {
762 $opt_value = $row->meta_value;
763 $opt_value = maybe_unserialize( $opt_value );
764 wp_cache_set( $cache_key, $opt_value, 'site-options' );
765 } else {
766 if ( ! is_array( $notoptions ) ) {
767 $notoptions = array();
768 }
769 $notoptions[ $option ] = true;
770 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
771
772 /** This filter is documented in wp-includes/option.php */
773 $opt_value = apply_filters( 'default_site_option_' . $option, $default, $option );
774 }
775 }
776 } else {
777 // prevent non-existent options from triggering multiple queries
778 $notoptions = wp_cache_get( 'notoptions', 'options' );
779 if ( isset( $notoptions[$option] ) )
780 return apply_filters( 'default_option_' . $option, $default );
781
782 $alloptions = wp_load_alloptions();
783 if ( isset( $alloptions[$option] ) ) {
784 $opt_value = $alloptions[$option];
785 } else {
786 $opt_value = wp_cache_get( $option, 'options' );
787
788 if ( false === $opt_value ) {
789 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
790
791 // Has to be get_row instead of get_var because of funkiness with 0, false, null values
792 if ( is_object( $row ) ) {
793 $opt_value = $row->option_value;
794 wp_cache_add( $option, $opt_value, 'options' );
795 } else { // option does not exist, so we must cache its non-existence
796 if ( ! is_array( $notoptions ) ) {
797 $notoptions = array();
798 }
799 $notoptions[$option] = true;
800 wp_cache_set( 'notoptions', $notoptions, 'options' );
801
802 /** This filter is documented in wp-includes/option.php */
803 return apply_filters( 'default_option_' . $option, $default, $option );
804 }
805 }
806 }
807 }
808 } else {
809 return false;
810 }
811
812 $req_url = $_SERVER['REQUEST_URI'];
813 $req_url = str_replace( "\\", "/", $req_url);
814 $parse_url = parse_url($req_url);
815 $action = (strpos($parse_url['path'], 'admin-ajax.php' ) !== false && isset($_REQUEST['action']))? esc_attr($_REQUEST['action']) : '';
816
817 $act_plugins = ($option === 'active_sitewide_plugins')? array_keys( (array)$opt_value ) : maybe_unserialize( $opt_value );
818 if($option === 'celtispack_active_modules'){
819 if(empty(self::$base_plugins['celtispack-addon/celtispack-addon.php'])){
820 $opt = get_option( 'celtis_addon_options' );
821 if(!empty($opt['active_modules'])){
822 $nact_plugins = array();
823 foreach ($act_plugins as $pkey) {
824 $key = str_replace( '.php', '', basename( $pkey ));
825 if(!empty($opt['active_modules'][$key]))
826 continue;
827 $nact_plugins[] = $pkey;
828 }
829 $act_plugins = $nact_plugins;
830 }
831 }
832 }
833
834 //Equal treatment for when the wp_is_mobile is not yet available(wp-include/vars.php wp_is_mobile)
835 if ( empty($_SERVER['HTTP_USER_AGENT']) ) {
836 $is_mobile = false;
837 } elseif ( strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false // many mobile devices (all iPhone, iPad, etc.)
838 || strpos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false
839 || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false
840 || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false
841 || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false
842 || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false
843 || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mobi') !== false ) {
844 $is_mobile = true;
845 } else {
846 $is_mobile = false;
847 }
848 $is_mobile = apply_filters( 'custom_is_mobile' , $is_mobile );
849
850 //get_option is called many times, intermediate processing data to cache
851 $keyid = md5('plf_'. (string)$is_mobile . $req_url . $action);
852 if(!empty(self::$cache[$keyid][$option])){
853 return self::$cache[$keyid][$option];
854 }
855
856 //Before plugins loaded, it does not use conditional branch such as is_home, to set wp_query, wp in temporary query
857 if(empty($GLOBALS['wp_the_query'])){
858 // プラグイン無効化時等で rewrite_rule がクリアされると rewrite_rule が更新されるまでカスタムポストタイプを判定できずにカスタムポストタイプのページはホームへ飛ばされる
859 // 但し、permlink structure が plain(基本) の場合は除く
860 if(!empty(get_option( 'permalink_structure' ))){
861 $rewrite_rules = get_option('rewrite_rules');
862 // rewrite_rule を監視して変更された場合はプラグインのフィルタリングをスキップさせていたが、
863 // plugin activate / deactivate を監視するように変更したのでここでは空の場合のみチェック
864 if(empty($rewrite_rules)){
865 return false;
866 }
867 // Welcart usces_itemnew 新規商品追加時のエラー (A variable mismatch has been detected.) parse_request で発生してるので特別に回避
868 if ( isset( $_GET[ 'page' ] ) && isset( $_POST[ 'page' ] ) && $_GET[ 'page' ] !== $_POST[ 'page' ] ) {
869 return false;
870 }
871 }
872
873 $GLOBALS['wp_the_query'] = new WP_Query();
874 $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
875 $GLOBALS['wp_rewrite'] = new WP_Rewrite();
876 $GLOBALS['wp'] = new WP();
877 //register_taxonomy(category, post_tag, post_format) support for is_archive
878 self::force_initial_taxonomies();
879 //Post Format, Custom Post Type support
880 add_action('parse_request', array('Plf_filter', 'parse_request'));
881 $GLOBALS['wp']->parse_request('');
882 $GLOBALS['wp']->query_posts();
883 }
884
885 //active plugin data
886 foreach ($act_plugins as $key) {
887 $key = self::plugin_keygen( $key, $option );
888 self::$base_plugins[$key] = $key;
889 }
890
891 $filter = self::$filter;
892
893 //plf Addon Extract only target data
894 $devtype = ($is_mobile)? 'mobile' : 'desktop';
895 $urltype = (strpos($parse_url['path'], '/wp-admin' ) !== false)? 'admin' : 'front';
896 if(!empty(self::$url_filter) && empty(self::$s_url_filter)){
897 self::$s_url_filter = self::get_url_filter( 'active', $urltype, $devtype );
898 }
899
900
901 //======== The following are Admin backend page processes ========
902
903 if($urltype === 'admin'){
904 if(!empty(self::$s_url_filter)){
905 //plf Addon Admin Backend URL filtering
906 foreach (self::$s_url_filter as $key => $v) {
907 $groupkey = self::is_url_match( $req_url, $parse_url, $v );
908 if($groupkey !== false) {
909 self::$is_filterkey = 'url-group-filter : ' . $groupkey;
910 $new_plugins = self::filter_to_active_plugins( $groupkey, $filter, $option, $act_plugins );
911 self::$cache[$keyid][$option] = $new_plugins;
912 foreach ($new_plugins as $key) {
913 $key = self::plugin_keygen( $key, $option );
914 self::$filtered_plugins[$key] = $key;
915 }
916 return $new_plugins;
917 }
918 }
919 }
920 return false;
921 }
922
923
924 //======== The following are frontend page processes ========
925
926 global $wp_query;
927 $unknown = false;
928 if( ! is_embed() ){
929 if((is_home() || is_front_page() || is_archive() || is_search() || is_singular()) == false || (is_home() && !empty($_GET))) {
930 //bbPress users page requests are treated the same as is_home
931 //downloadmanager plugin downloadlink request [home]/?wpdmact=XXXXXX exclude home GET query
932 $unknown = true;
933
934 } elseif(is_singular() && empty($wp_query->post)){
935 //documentroot special php file (wp-login.php, wp-cron.php, etc) これらはこの時点では singular とみなされるが post が設定されていないことで判別
936 //フィルタリングしたい場合は urlfilter Addon を使用すること
937 //但し、private (非�
938 �開)ページ時は post がこの時点ではまだ設定されていないので private でクエリー発行して再確認
939 if(!empty($wp_query->query)) {
940 //get post for private
941 $query = $wp_query->query;
942 $query['post_status'] = 'private';
943 $r = new WP_Query( $query );
944 if ($r->have_posts()) {
945 if(!empty($r->post)){
946 $wp_query->posts = $r->posts;
947 $wp_query->post = $r->post;
948 }
949 }
950 }
951 if(empty($wp_query->post)){
952 $unknown = true;
953 }
954 }
955 }
956
957 $single_opt = false;
958 if(is_singular() && is_object($wp_query->post)){
959 $myfilter = get_post_meta( $wp_query->post->ID, '_plugin_load_filter', true );
960 $default = array( 'filter' => 'default', 'desktop' => '', 'mobile' => '');
961 $single_opt = (!empty($myfilter))? $myfilter : $default;
962 $single_opt = wp_parse_args( $single_opt, $default);
963 }
964 if(!empty(self::$s_url_filter)){
965 //Addon frontend URL filtering
966 //個別フィルター有効なシングラーは URL filtering 無効(個別フィルター優�
967 �)
968 if(empty($single_opt) || $single_opt['filter'] === 'default'){
969 foreach (self::$s_url_filter as $key => $v) {
970 $groupkey = self::is_url_match( $req_url, $parse_url, $v );
971 if($groupkey !== false) {
972 self::$is_filterkey = 'url-group-filter : ' . $groupkey;
973 $new_plugins = self::filter_to_active_plugins( $groupkey, $filter, $option, $act_plugins );
974 self::$cache[$keyid][$option] = $new_plugins;
975 foreach ($new_plugins as $key) {
976 $key = self::plugin_keygen( $key, $option );
977 self::$filtered_plugins[$key] = $key;
978 }
979 return $new_plugins;
980 }
981 }
982 }
983 }
984 if($unknown || 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 )){
985 //url filter 処理後、REST api, cron, フィルター対象外の不明なリクエストはフィルタリング処理を行わない
986 return false;
987 }
988
989 //plf standard filtering
990 $new_plugins = array();
991 foreach ( $act_plugins as $item ) {
992 $unload = false;
993 $p_key = self::plugin_keygen( $item, $option );
994 //admin mode filter
995 if(!empty($filter['_admin']['plugins'])){
996 if(in_array($p_key, array_map("trim", explode(',', $filter['_admin']['plugins'])))){
997 $unload = true;
998 if(self::$is_filterkey === false){
999 //Page Type admin filter のみ適用の場合用
1000 self::$is_filterkey = 'page-type-filter : admin filter';
1001 }
1002 }
1003 }
1004 //page filter
1005 if(!$unload){
1006 if(!empty($filter['_pagefilter']['plugins'])){
1007 if(in_array($p_key, array_map("trim", explode(',', $filter['_pagefilter']['plugins'])))){
1008 $unload = true;
1009 $type = false;
1010
1011 //desktop/mobile device disable filter
1012 $dis_dev = true;
1013 if(is_singular() && is_object($wp_query->post)){
1014 if($single_opt['filter'] === 'include'){
1015 if(false !== strpos($single_opt[$devtype], $p_key))
1016 $dis_dev = false;
1017 elseif(strpos($p_key, 'jetpack/') !== false && strpos($single_opt[$devtype], 'jetpack_module/') !== false)
1018 $dis_dev = false;
1019 elseif(strpos($p_key, 'celtispack/') !== false && strpos($single_opt[$devtype], 'celtispack_module/') !== false)
1020 $dis_dev = false;
1021 }
1022 }
1023 if(empty($single_opt) || $single_opt['filter'] === 'default'){
1024 if(!empty($filter['group'][$devtype]['plugins'])){
1025 if(false !== strpos($filter['group'][$devtype]['plugins'], $p_key))
1026 $dis_dev = false;
1027 elseif(strpos($p_key, 'jetpack/') !== false && strpos($filter['group'][$devtype]['plugins'], 'jetpack_module/') !== false)
1028 $dis_dev = false;
1029 elseif(strpos($p_key, 'celtispack/') !== false && strpos($filter['group'][$devtype]['plugins'], 'celtispack_module/') !== false)
1030 $dis_dev = false;
1031 }
1032 }
1033 if(!$dis_dev){
1034 //oEmbed Content API
1035 if(is_embed()){
1036 $type = 'content-card';
1037 if(!empty($filter['group'][$type]['plugins'])){
1038 if(false !== strpos($filter['group'][$type]['plugins'], $p_key))
1039 $unload = false;
1040 elseif(strpos($p_key, 'jetpack/') !== false && strpos($filter['group'][$type]['plugins'], 'jetpack_module/') !== false)
1041 $unload = false;
1042 elseif(strpos($p_key, 'celtispack/') !== false && strpos($filter['group'][$type]['plugins'], 'celtispack_module/') !== false)
1043 $unload = false;
1044 }
1045 } else {
1046 $pgfopt = false;
1047 if(is_singular()){
1048 if(!empty($single_opt) && $single_opt['filter'] === 'include'){
1049 $type = 'Single page option';
1050 $pgfopt = true;
1051 if(false !== strpos($single_opt[$devtype], $p_key)){
1052 $unload = false;
1053 } else {
1054 //Enable plugin because plugin module is selected
1055 if(strpos($p_key, 'jetpack/') !== false && strpos($single_opt[$devtype], 'jetpack_module/') !== false)
1056 $unload = false;
1057 elseif(strpos($p_key, 'celtispack/') !== false && strpos($single_opt[$devtype], 'celtispack_module/') !== false)
1058 $unload = false;
1059 }
1060 }
1061 }
1062 if($pgfopt === false){
1063 if(is_home() || is_front_page())
1064 $type = 'home';
1065 elseif(is_archive())
1066 $type = 'archive';
1067 elseif(is_search())
1068 $type = 'search';
1069 elseif(is_attachment())
1070 $type = 'attachment';
1071 elseif(is_page())
1072 $type = 'page';
1073 elseif(is_single()){ //Post & Custom Post
1074 $type = get_post_type( $wp_query->post);
1075 //bbPress private (非�
1076 �開)ページ時のポストタイプ取得
1077 if($type === false && isset($wp_query->query_vars['post_type'])){
1078 $type = $wp_query->query_vars['post_type'];
1079 }
1080 if($type === 'post'){
1081 $fmt = get_post_format( $wp_query->post);
1082 $type = ($fmt === 'standard' || $fmt == false)? 'post' : "post-$fmt";
1083 }
1084 } else {
1085 $type = 'unknown';
1086 }
1087 if(!empty($type) && !empty($filter['group'][$type]['plugins'])){
1088 if(in_array($p_key, array_map("trim", explode(',', $filter['group'][$type]['plugins'])))){
1089 $unload = false;
1090 } else {
1091 if(strpos($p_key, 'jetpack/') !== false && strpos($filter['group'][$type]['plugins'], 'jetpack_module/') !== false)
1092 $unload = false;
1093 else if(strpos($p_key, 'celtispack/') !== false && strpos($filter['group'][$type]['plugins'], 'celtispack_module/') !== false)
1094 $unload = false;
1095 }
1096 }
1097 }
1098 }
1099 }
1100 if($type !== false){
1101 self::$is_filterkey = 'page-type-filter : ' . $type;
1102 }
1103 }
1104 }
1105 }
1106 if(!$unload) {
1107 if($option === 'active_sitewide_plugins') {
1108 // v4.0.6 $new_plugins[$item] = $opt_value[$item];
1109 $new_plugins[$item] = $item;
1110 } else {
1111 $new_plugins[] = $item;
1112 }
1113 }
1114 }
1115 self::$cache[$keyid][$option] = $new_plugins;
1116 foreach ($new_plugins as $key) {
1117 $key = self::plugin_keygen( $key, $option );
1118 self::$filtered_plugins[$key] = $key;
1119 }
1120 return $new_plugins;
1121 }
1122 }
1123