PluginProbe
Plugin Load Filter / trunk
Plugin Load Filter vtrunk
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 / plugin-load-filter.php

plugin-load-filter.php in Plugin Load Filter trunk, at plugin-load-filter.php

1,368 lines 74.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
4 Description: Dynamically activate the selected plugins for each page. Response will be faster by filtering plugins.
5 Version: 4.4.1
6 Plugin URI: https://celtislab.net/en/wp-plugin-load-filter
7 Author: enomoto@celtislab
8 Author URI: https://celtislab.net/
9 Requires at least: 6.3
10 Tested up to: 7.0
11 Requires PHP: 8.1
12 License: GPLv2
13 Text Domain: plf
14 Domain Path: /languages
15 */
16
17 defined( 'ABSPATH' ) || exit;
18
19 /***************************************************************************
20 * plugin activation / deactivation / uninstall
21 **************************************************************************/
22 if(is_admin()){
23 //deactivation
24 function plugin_load_filter_deactivation( $network_deactivating ) {
25 $act = false;
26 if (is_multisite()) {
27 if(! $network_deactivating){
28 global $wpdb;
29 $current_blog_id = get_current_blog_id();
30 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
31 foreach ( $blog_ids as $blog_id ) {
32 if($blog_id == $current_blog_id){
33 //current site
34 }
35 else {
36 //other site active check
37 switch_to_blog( $blog_id );
38 if ( is_plugin_active( plugin_basename( __FILE__ )))
39 $act = true;
40 }
41 }
42 switch_to_blog( $current_blog_id );
43 }
44 }
45 if($act === false){
46 flush_rewrite_rules(); //options data 'rewrite_rules' clear for remake.
47 if ( file_exists( WPMU_PLUGIN_DIR . "/plf-filter.php" )) {
48 @unlink( WPMU_PLUGIN_DIR . '/plf-filter.php' );
49 }
50 }
51 }
52 register_deactivation_hook( __FILE__, 'plugin_load_filter_deactivation' );
53
54 //uninstall
55 function plugin_load_filter_uninstall() {
56
57 if ( !is_multisite()) {
58 delete_option('plf_queryvars');
59 delete_option('plf_option' );
60 delete_option('plf_addon_options');
61 } else {
62 global $wpdb;
63 $current_blog_id = get_current_blog_id();
64 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
65 foreach ( $blog_ids as $blog_id ) {
66 switch_to_blog( $blog_id );
67 delete_option('plf_queryvars');
68 delete_option('plf_option' );
69 delete_option('plf_addon_options');
70 }
71 switch_to_blog( $current_blog_id );
72 }
73 if ( file_exists( WPMU_PLUGIN_DIR . "/plf-filter.php" )) {
74 @unlink( WPMU_PLUGIN_DIR . '/plf-filter.php' );
75 }
76 }
77 register_uninstall_hook(__FILE__, 'plugin_load_filter_uninstall');
78
79 }
80
81 $Plf_setting = new Plf_setting();
82
83 class Plf_setting {
84
85 static $plugins_inf = ''; //active plugin/module infomation
86 static $filter = array(); //filter option data
87 private $tab_num = 0;
88
89 /***************************************************************************
90 * Style Sheet
91 **************************************************************************/
92 function plf_css() { ?>
93 <style type="text/css">
94 #plugin-filter-select {margin-top: 12px;}
95 #plugin-filter-select p {margin: 1em 0;}
96 #page-filter-stat { margin-top: 12px;}
97 #activation-table { padding-bottom: 8px; border: 1px solid #eee;}
98 #activation-table th { text-align: center;}
99 #activation-table td { font-size: 97%;}
100 #activation-table input[type=checkbox] { height: 25px; width: 25px; opacity: 0;}
101 #plf-post-locale-select { margin-top: 16px;}
102 thead .plugins-name { background-color: aliceblue;}
103 thead .device-type { background-color: oldlace;}
104 thead .plugins-name, tbody .plugins-name { min-width: 144px; max-width: 200px; padding: 3px 3px 3px 5px;}
105 thead .device-type, tbody .device-type { min-width: 40px; max-width: 40px; text-align: center; padding: 5px 1px 2px;}
106 .dashicons-yes:before { font-size: 20px; border: 1px solid #eee; background-color: whitesmoke;}
107 .device-type label { color: whitesmoke; }
108 input.altcheckbox[type="checkbox"] { -webkit-appearance: none; appearance: none; position: absolute;}
109 .device-type input.altcheckbox[type="checkbox"]:checked + span.dashicons-yes:before { background-color: yellowgreen; }
110 .plf-option-info { font-size:12px; margin:10px 0; padding:3px; background-color:#fff8e5;}
111 .edit-post-locale-link span.dashicons { width: 0.8em; height: 0.8em; margin: -0.4em 0.1em 0; vertical-align: middle; text-decoration: initial;}
112 </style>
113 <?php }
114
115 function jquery_tab_css() { ?>
116 <style type="text/css">
117 .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.5; text-decoration: none; font-size: 100%; list-style: none; }
118 .ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
119 .ui-helper-clearfix:after { clear: both; }
120 .ui-helper-clearfix { zoom: 1; }
121 .ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
122 .ui-tabs .ui-tabs-nav { margin: 1px 8px; padding: .2em .2em; }
123 .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .3em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
124 .ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; }
125 .ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
126 .ui-tabs .ui-tabs-panel { display: block; border-width: 0; background: none; }
127 .ui-tabs .ui-tabs-nav a { margin: 8px 10px; }
128 .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #dddddd; background-color: #f4f4f4; font-weight: bold; color: #0073ea; }
129 .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #0073ea; text-decoration: none; }
130 .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus { border: 1px solid #0073ea; background-color: #0073ea; font-weight: bold; color: #ffffff; }
131 .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #dddddd; background-color: #0073ea; font-weight: bold; color: #ffffff; }
132 .ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #ffffff; text-decoration: none; }
133 .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
134
135 #wrap_registration-table, #wrap_activation-table { overflow:auto; height:600px; position: relative;}
136 #registration-table input[type=radio], #registration-table input[type=checkbox], #activation-table input[type=checkbox] { height: 25px; width: 25px; opacity: 0;}
137 #registration-table th {text-align: center;}
138 thead, tbody { display: block;}
139 .widefat * { word-wrap: break-word !important;}
140 .widefat thead { position:sticky; top:0px; z-index:1;}
141 .widefat tr:first-of-type th:first-of-type {position: sticky; left: 0px; text-align: left; background-color: aliceblue; z-index:3;}
142 .widefat th { padding: 8px;}
143 .widefat td { padding: 8px;}
144 .widefat td:first-of-type { position: sticky; left: 0px; text-align: left; background-color: white;}
145 thead .filter-plugins-name, thead .plugins-name { background-color: aliceblue;}
146 thead .urlfilter { background-color: lavenderblush;}
147 .filter-none, .filter-admin, .filter-tmpl { background-color: honeydew;}
148 thead .device-type { background-color: oldlace;}
149 thead .ckbox-type { background-color: lavender;}
150 thead .pformat { background-color: honeydew;}
151 thead .tmpl-embed { background-color: lightyellow;}
152 thead .tmpl-custom { background-color: lavenderblush;}
153 thead .filter-plugins-name, tbody .filter-plugins-name { min-width: 240px; max-width: 240px;}
154 thead .plugins-name, tbody .plugins-name { min-width: 180px; max-width: 180px;}
155 thead .device-type, tbody .device-type, thead .ckbox-type, tbody .ckbox-type, thead .deny-type, tbody .deny-type { min-width: 40px; max-width: 40px; text-align: center;}
156 thead .filter-type, tbody .filter-type { min-width: 56px; max-width: 56px; text-align:center;}
157 .urlfilter-description { padding: 0 10px 15px;}
158 .grid-row { display: flex; flex-flow: row wrap;}
159 .filter-description { padding: 0 10px; width:62%;}
160 .side-info { width: 30%; padding-left: 24px;}
161 .ckbox-list { padding: 4px 0 12px}
162 .ckbox-list label { white-space:nowrap;}
163 .ckbox-list span { margin-right: 12px; }
164 .dashicons:before { font-size: 24px; }
165 .radio-green label, .radio-red label { color: #ddd; margin-left: -32px; }
166 .ckbox-type label { color: #ddd;}
167 .radio-green input[type="radio"]:checked + span { color: #8bc34a; }
168 .radio-red input[type="radio"]:checked + span { color: tomato; }
169 .ckbox-type input[type="checkbox"]:checked + span { color: #4caf50; }
170 .deny-type label { color: #4caf50;}
171 .deny-type input.altcheckbox[type="checkbox"]:checked + span { color: #ddd; }
172 .dashicons-yes:before { font-size: 20px; border: 1px solid #eee; }
173 .device-type input.altcheckbox[type="checkbox"]:checked + span.dashicons-yes:before { background-color: yellowgreen; }
174 .option-item { margin-bottom: 28px; }
175 </style>
176 <?php }
177
178 /***************************************************************************
179 * Plugin Load Filter Option Setting
180 **************************************************************************/
181
182 public function __construct() {
183
184 self::$filter = get_option('plf_option', array());
185 if(empty(self::$filter['optver']) || self::$filter['optver'] < '2'){
186 self::$filter['optver'] = '2';
187 //ここにデータフォーマットが変わった場合の変換処理を記述
188 }
189 if(!empty(self::$filter['language'])){
190 add_action( 'wp_head', array('Plf_setting', 'altenate_hreflang') );
191 }
192
193 if(is_admin()) {
194 add_action( 'plugins_loaded', array(&$this, 'plf_admin_start'), 9999 );
195 add_action( 'admin_init', array(&$this, 'action_posts'));
196 add_action( 'add_meta_boxes', array(&$this, 'load_meta_boxes'), 10, 2 );
197 }
198 add_action( 'wp_ajax_plugin_load_filter', array(&$this, 'plf_ajax_postidfilter'));
199 }
200
201 //Plugin Load Filter admin setting start
202 public function plf_admin_start() {
203 require_once(ABSPATH . 'wp-admin/includes/plugin.php');
204
205 self::$plugins_inf = get_plugins();
206 //Ver4.0.0 でしか呼び出せないメソッドを呼び出さないよう新設した switch_theme があるかどうかで判定
207 if(method_exists('Plf_filter', 'switch_theme')){
208 if(class_exists('Plf_filter')){
209 if ( is_multisite() )
210 remove_filter('pre_site_option_active_sitewide_plugins', array('Plf_filter', 'active_sitewide_plugins'));
211 remove_filter('pre_option_active_plugins', array('Plf_filter', 'active_plugins'));
212 }
213 foreach ( self::$plugins_inf as $plugin_key => $a_plugin ) {
214 if(is_plugin_inactive( $plugin_key )){
215 unset(self::$plugins_inf[$plugin_key]);
216 }
217 }
218 if(class_exists('Plf_filter')){
219 if ( is_multisite() )
220 add_filter('pre_site_option_active_sitewide_plugins', array('Plf_filter', 'active_sitewide_plugins'));
221 add_filter('pre_option_active_plugins', array('Plf_filter', 'active_plugins'));
222 }
223
224 //jetpack active module
225 if(method_exists('Jetpack', 'get_module')){
226 if(class_exists('Plf_filter')){
227 remove_filter('pre_option_jetpack_active_modules', array('Plf_filter', 'active_jetmodules'));
228 }
229 $modules = Jetpack::get_active_modules();
230 $modules = array_diff( $modules, array( 'vaultpress' ) );
231 foreach ( $modules as $key => $module_name ) {
232 if(!empty($module_name)){
233 $module = Jetpack::get_module( $module_name );
234 if(!empty($module))
235 self::$plugins_inf['jetpack_module/' . $module_name] = $module;
236 }
237 }
238 if(class_exists('Plf_filter')){
239 add_filter('pre_option_jetpack_active_modules', array('Plf_filter', 'active_jetmodules'));
240 }
241 }
242 //celtispack active module
243 if(method_exists('Celtispack', 'get_module')){
244 if(class_exists('Plf_filter')){
245 remove_filter('pre_option_celtispack_active_modules', array('Plf_filter', 'active_celtismodules'));
246 }
247 $modules = Celtispack::get_active_modules();
248 foreach ( $modules as $key => $module_name ) {
249 if(!empty($module_name)){
250 self::$plugins_inf['celtispack_module/' . $module_name] = Celtispack::get_module( $module_name );
251 }
252 }
253 if(class_exists('Plf_filter')){
254 add_filter('pre_option_celtispack_active_modules', array('Plf_filter', 'active_celtismodules'));
255 }
256 }
257 if ( empty( self::$plugins_inf ) )
258 return;
259 }
260
261 add_action('admin_menu', array(&$this, 'plf_option_menu'));
262 }
263
264 static function get_plugins_inf() {
265 $inf = (!empty(self::$plugins_inf))? self::$plugins_inf : false;
266 return $inf;
267 }
268
269 //Plugins sub menu add
270 public function plf_option_menu() {
271 if(current_user_can( 'activate_plugins' )){
272 $page = add_menu_page( 'Plugin Load FIlter Settings', esc_html__('Plugin Load Filter', 'plf'), 'manage_options', 'plugin_load_filter_admin_manage_page', array(&$this, 'plf_option_page'), 'dashicons-filter', '65.1');
273 add_submenu_page( 'plugin_load_filter_admin_manage_page', 'Plugin Load FIlter Settings', esc_html__('General Settings', 'plf'), 'manage_options', 'plugin_load_filter_admin_manage_page', array(&$this, 'plf_option_page') );
274 add_action( 'admin_print_scripts-'.$page, array(&$this, 'plf_scripts') );
275 add_action( 'admin_print_scripts-'.$page, array(&$this, 'deploy_mu_plugins'));
276 }
277 }
278
279 //Plugin Load Filter setting page script
280 function plf_scripts() {
281 wp_enqueue_script( 'jquery' );
282 wp_enqueue_script( 'jquery-ui-core' );
283 wp_enqueue_script( 'jquery-ui-widget' );
284 wp_enqueue_script( 'jquery-ui-tabs' );
285 add_action( 'admin_head', array(&$this, 'plf_css' ));
286 add_action( 'admin_head', array(&$this, 'jquery_tab_css' ));
287 add_action( 'admin_footer', array(&$this, 'activetab_script' ));
288 add_action( 'admin_notices', array('Plf_setting', 'plf_notice'));
289 }
290
291 //plf-filter.php mu-plugins module set
292 public function deploy_mu_plugins() {
293 if(wp_mkdir_p( WPMU_PLUGIN_DIR )){
294 if ( !file_exists( WPMU_PLUGIN_DIR . "/plf-filter.php" )) {
295 @copy(__DIR__ . '/mu-plugins/plf-filter.php', WPMU_PLUGIN_DIR . '/plf-filter.php');
296 }
297 else {
298 require_once(ABSPATH . 'wp-admin/includes/plugin.php');
299 $dp = get_plugin_data( WPMU_PLUGIN_DIR . "/plf-filter.php", false, false );
300 $sp = get_plugin_data( __DIR__ . '/mu-plugins/plf-filter.php', false, false );
301 if(version_compare( $dp['Version'], $sp['Version'], '!=')){
302 @copy(__DIR__ . '/mu-plugins/plf-filter.php', WPMU_PLUGIN_DIR . '/plf-filter.php');
303 }
304 }
305 }
306 }
307
308 //Notice Message display
309 static function plf_notice() {
310 $notice = get_transient('plf_notice');
311 if(!empty($notice)){
312 echo '<div class="notice notice-warning"><p>Plugin Load Filter : ' . esc_html($notice) . '</p></div>';
313 delete_transient('plf_notice');
314 }
315 }
316
317 //plugin filter option action request (add, update, delete)
318 function action_posts() {
319 if (current_user_can( 'activate_plugins' )) {
320 if( isset($_POST['edit_regist_filter']) ) {
321 if(isset($_POST['plfregist'])){
322 check_admin_referer('plugin_load_filter');
323 //url filter
324 $groupkeys = (method_exists('Plf_filter', 'get_active_group'))? Plf_filter::get_active_group() : array();
325 if(!empty($groupkeys) && isset($_POST['plfurlkey'])){
326 $plfurlkey = $_POST['plfurlkey']; //array
327 foreach( $groupkeys as $item){
328 if(empty( $plfurlkey[$item])){
329 self::$filter['plfurlkey'][$item]['plugins'] = '';
330 } else {
331 $plugins = array();
332 foreach ( $plfurlkey[$item] as $p_key => $val ) {
333 if($val == '1')
334 $plugins[] = sanitize_text_field($p_key);
335 }
336 $option["plugins"] = implode(",", $plugins);
337 self::$filter['plfurlkey'][$item] = $option;
338 }
339 }
340 }
341 //page type filter
342 foreach( array('_admin', '_pagefilter') as $item){
343 $plugins = array();
344 $plfregist = $_POST['plfregist']; //array
345 foreach ( $plfregist as $p_key => $val ) {
346 if($val == $item){
347 $p_key = sanitize_text_field($p_key);
348 $plugins[$p_key] = sanitize_text_field($val);
349 }
350 }
351 if($item == '_pagefilter'){
352 //If all modules is specified filter, in some cases you want to deactivate plugin itself.
353 $jbase = $cbase = '';
354 $jall = $call = true;
355 foreach ( $plfregist as $p_key => $val ) {
356 $p_key = sanitize_text_field($p_key);
357 if(strpos($p_key, 'jetpack/') !== false)
358 $jbase = $p_key;
359 else if(strpos($p_key, 'celtispack/') !== false)
360 $cbase = $p_key;
361 else if(strpos($p_key, 'jetpack_module/') !== false){
362 if($val != '_pagefilter' && $val != '_admin'){
363 $jall = false;
364 }
365 }
366 else if(strpos($p_key, 'celtispack_module/') !== false){
367 if($val != '_pagefilter' && $val != '_admin')
368 $call = false;
369 }
370 }
371 if(!empty($jbase) && $jall === false)
372 unset($plugins[$jbase]);
373 if(!empty($cbase) && $call === false)
374 unset($plugins[$cbase]);
375 }
376 $option["plugins"] = implode(",", array_keys($plugins));
377 self::$filter[$item] = $option;
378 }
379 //exclude option
380 if(isset($_POST['plf_option']['exclude'])){
381 $exclude = array();
382 $optexcl = $_POST['plf_option']['exclude']; //array
383 foreach ( $optexcl as $ft => $v ) {
384 if(!empty($v)){
385 $ft = sanitize_text_field($ft);
386 $exclude[$ft] = true;
387 }
388 }
389 self::$filter['exclude'] = $exclude;
390 } else {
391 self::$filter['exclude'] = array();
392 }
393
394 //hide singlr post filter for custom post type
395 if(isset($_POST['plf_option']['hidecpt'])){
396 $hidecpt = array();
397 $optcpt = $_POST['plf_option']['hidecpt']; //array
398 foreach ( $optcpt as $ft => $v ) {
399 if(!empty($v)){
400 $ft = sanitize_text_field($ft);
401 $hidecpt[$ft] = true;
402 }
403 }
404 self::$filter['hidecpt'] = $hidecpt;
405 } else {
406 self::$filter['hidecpt'] = array();
407 }
408
409 //admin bar (filtered stat)
410 self::$filter['admin_bar'] = (isset($_POST['plf_option']['admin_bar']))? 1 : 0;
411
412 //Language option
413 self::$filter['language'] = (isset($_POST['plf_option']['language']))? 1 : 0;
414
415 //Ajax acceleration plugin filter (for plugin developers)
416 self::$filter['ajax_accelfilter'] = (isset($_POST['plf_option']['ajax_accelfilter']))? 1 : 0;
417
418 update_option('plf_option', self::$filter, 'no' );
419 }
420 header('Location: ' . admin_url('plugins.php?page=plugin_load_filter_admin_manage_page'));
421 exit;
422
423 } elseif( isset($_POST['clear_regist_filter']) ) {
424 check_admin_referer('plugin_load_filter');
425 if(!empty(self::$filter['plfurlkey'])){
426 foreach (self::$filter['plfurlkey'] as $key => $val) {
427 unset(self::$filter['plfurlkey'][$key]);
428 }
429 }
430 foreach( array('_admin', '_pagefilter') as $item){
431 self::$filter[$item] = array();
432 }
433 self::$filter['exclude'] = array();
434 self::$filter['hidecpt'] = array();
435
436 //old data unset
437 if(isset(self::$filter['urlkey'])){
438 unset(self::$filter['urlkey']);
439 }
440 if(isset(self::$filter['urlkeylist'])){
441 unset(self::$filter['urlkeylist']);
442 }
443
444 self::$filter['admin_bar'] = 0;
445 self::$filter['language'] = 0;
446 self::$filter['ajax_accelfilter'] = 0;
447 update_option('plf_option', self::$filter, 'no' );
448 header('Location: ' . admin_url('plugins.php?page=plugin_load_filter_admin_manage_page'));
449 exit;
450
451 } else if(isset($_POST['edit_activate_page_filter']) ) {
452 if(isset($_POST['plfactive'])){
453 check_admin_referer('plugin_load_filter');
454 self::$filter['group'] = array();
455 $plfactive = $_POST['plfactive']; //array
456 $group = array_keys($plfactive);
457 foreach( $group as $item){
458 $plugins = array();
459 foreach ( $plfactive[$item] as $p_key => $val ) {
460 if($val == '1')
461 $plugins[] = sanitize_text_field($p_key);
462 }
463 $option["plugins"] = implode(",", $plugins);
464 self::$filter['group'][$item] = $option;
465 }
466 update_option('plf_option', self::$filter, 'no' );
467 }
468 header('Location: ' . admin_url('plugins.php?page=plugin_load_filter_admin_manage_page&action=tab_1'));
469 exit;
470
471 } elseif( isset($_POST['clear_activate_page_filter']) ) {
472 check_admin_referer('plugin_load_filter');
473 self::$filter['group'] = array();
474 update_option('plf_option', self::$filter, 'no' );
475 header('Location: ' . admin_url('plugins.php?page=plugin_load_filter_admin_manage_page&action=tab_1'));
476 exit;
477 }
478 if(!empty($_GET['action']) && $_GET['action']=='tab_1') {
479 $this->tab_num = 1;
480 }
481 }
482 }
483
484 //Plugin or Module key to name
485 // $type : list/smart/tree
486 static function pluginkey_to_name( $infkey, $type='list') {
487 $name = '';
488 if(strpos($infkey, 'jetpack_module/') !== false){
489 if(!empty(self::$plugins_inf[$infkey]['name'])){
490 $m_mark = ($type !== 'list')? '-' : 'Jetpack-';
491 if($type === 'smart') {
492 if(empty(self::$filter['_pagefilter']['plugins']) || strpos(self::$filter['_pagefilter']['plugins'], 'jetpack/') === false)
493 $name = $m_mark . self::$plugins_inf[$infkey]['name'];
494 } else {
495 $name = $m_mark . self::$plugins_inf[$infkey]['name'];
496 }
497 }
498 } elseif(strpos($infkey, 'celtispack_module/') !== false){
499 if(!empty(self::$plugins_inf[$infkey]['Name'])){
500 $m_mark = ($type !== 'list')? '-' : 'Celtispack-';
501 if($type === 'smart') {
502 if(empty(self::$filter['_pagefilter']['plugins']) || strpos(self::$filter['_pagefilter']['plugins'], 'celtispack/') === false)
503 $name = $m_mark . self::$plugins_inf[$infkey]['Name'];
504 } else {
505 $name = $m_mark . self::$plugins_inf[$infkey]['Name'];
506 }
507 }
508 } else {
509 if(!empty(self::$plugins_inf[$infkey]['Name']))
510 $name = self::$plugins_inf[$infkey]['Name'];
511 }
512 return($name);
513 }
514
515 // wp_kses() サニタイズで form,input,select タグを許可
516 public static function get_allowed_tags() {
517 global $allowedposttags;
518 $allowed_tags = $allowedposttags;
519 $allowed_tags['form'] = array( 'action' => true, 'accept' => true, 'accept-charset' => true, 'enctype' => true, 'method' => true, 'name' => true, 'target' => true );
520 $allowed_tags['label'] = array( 'for' => true );
521 $allowed_tags['input'] = array( 'type' => true, 'name' => true, 'value' => true, 'checked' => true);
522 $allowed_tags['select'] = array( 'name' => true, 'multiple' => true );
523 $allowed_tags['option'] = array( 'value' => true, 'selected' => true );
524 $allowed_tags['button'] = array( 'href' => true, 'onclick' => true);
525 $allowed_tags['a']['onclick'] = true;
526 $allowed_tags = array_map( '_wp_add_global_attributes', $allowed_tags );
527 return $allowed_tags;
528 }
529 //Checkbox for addon
530 static function checkbox($name, $value, $label = '') {
531 return "<label><input type='checkbox' name='$name' value='1' " . checked( $value, 1, false ). "/> $label</label>";
532 }
533 static function altcheckbox($name, $value, $label = '') {
534 return "<label><input type='checkbox' name='$name' class='altcheckbox' value='1' " . checked( $value, 1, false ). "/> $label</label>";
535 }
536
537 //dropdown list for addon
538 static function dropdown($name, $items, $selected, $args = null, $display = false) {
539 $defaults = array(
540 'id' => $name,
541 'none' => false,
542 'class' => null,
543 'multiple' => false,
544 );
545
546 if (!is_array($items))
547 return;
548
549 if (empty($items))
550 $items = array();
551
552 // Items is in key => value format. If value is itself an array, use only the 1st column
553 foreach ($items as $key => &$value) {
554 if (is_array($value))
555 $value = array_shift($value);
556 }
557
558 extract(wp_parse_args($args, $defaults));
559
560 // If 'none' arg provided, prepend a blank entry
561 if ($none) {
562 if ($none === true)
563 $none = '&nbsp;';
564 $items = array('' => $none) + $items; // Note that array_merge() won't work because it renumbers indexes!
565 }
566
567 if (!$id)
568 $id = $name;
569
570 $name = ($name) ? ' name="' . esc_html($name) . '"' : '';
571 $id = ($id) ? ' id="' . esc_html($id) . '"' : '';
572 $class = ($class)? ' class="'. esc_html($class). '"' : '';
573 $multiple = ($multiple) ? ' multiple="multiple"' : '';
574
575 $html = '<select' . $name . $id . $class . $multiple .'>';
576 foreach ((array) $items as $key => $label) {
577 $html .= '<option value="' . esc_html($key) . '" ' . selected($selected, $key, false) . '>' . esc_html($label) . '</option>';
578 }
579 $html .= '</select>';
580 if($display){
581 echo wp_kses( $html, array(
582 'select' => array( 'name' => true, 'id' => true, 'class' => true, 'multiple' => true ),
583 'option' => array( 'value' => true, 'selected' => true )
584 ));
585 } else {
586 return $html;
587 }
588 }
589
590 //安�
591 �な文字列から指定タグのみデコード(既存の翻訳ファイルへ影響せずにエスケープするために使用)
592 //&lt;strong&gt;Type&lt;/strong&gt -> <strong>Type</strong>
593 static function decode_safe_tag_e( $tag, $safe_str ) {
594 $safe_str = preg_replace_callback( "|&lt;($tag.*)&gt;(.*)&lt;/($tag)&gt;|im", function($matches){
595 $tag_attrs = str_replace( '&quot;', '"', $matches[1]);
596 return '<' . $tag_attrs . '>' . $matches[2] . '</' . $matches[3] . '>';
597 }, $safe_str);
598 echo wp_kses_post($safe_str);
599 }
600
601 public function plfregist_item($key, $chklist, $filter) {
602 $p_name = self::pluginkey_to_name($key);
603 $opt_name = "plfregist[$key]";
604 ?>
605 <tr id="plfregist_<?php echo esc_html($key); ?>">
606 <td class="filter-plugins-name"><?php echo esc_html($p_name); ?></td>
607 <?php
608 foreach($chklist as $urlkey){
609 $name = "plfurlkey[$urlkey][$key]";
610 $checked = (empty($filter['plfurlkey'][$urlkey]['plugins']) || false === strpos($filter['plfurlkey'][$urlkey]['plugins'], $key))? false : true;
611 echo '<td class="deny-type filter-type"><label><input type="checkbox" name="' . esc_html($name) . '" class="altcheckbox" value="1" ' . checked( $checked, 1, false ). '/> <span class="dashicons dashicons-admin-plugins"></span></label></td>';
612 }
613 $radio = '';
614 if(!empty($filter['_admin']['plugins']) && false !== strpos($filter['_admin']['plugins'], $key))
615 $radio = '_admin';
616 else if(!empty($filter['_pagefilter']['plugins']) && false !== strpos($filter['_pagefilter']['plugins'], $key))
617 $radio = '_pagefilter';
618 ?>
619 <td class="radio-green filter-type"><label><input type="radio" name="<?php echo esc_html($opt_name); ?>" value='' <?php checked('', $radio); ?>/><span class="dashicons dashicons-admin-plugins"></span></label></td>
620 <td class="radio-red filter-type"><label><input type="radio" name="<?php echo esc_html($opt_name); ?>" value="_admin" <?php checked('_admin', $radio); ?>/><span class="dashicons dashicons-admin-plugins"></span></label></td>
621 <td class="radio-red filter-type"><label><input type="radio" name="<?php echo esc_html($opt_name); ?>" value="_pagefilter" <?php checked('_pagefilter', $radio); ?>/><span class="dashicons dashicons-admin-plugins"></span></label></td>
622 </tr>
623 <?php
624 }
625
626 //Filterring plugins select
627 public function plfregist_table($plugins, $filter) {
628 ?>
629 <div id="wrap_registration-table">
630 <table id="registration-table" class="widefat">
631 <thead>
632 <?php
633 $groupkeys = (method_exists('Plf_filter', 'get_active_group'))? Plf_filter::get_active_group() : array();
634 $urlnum = count($groupkeys);
635 ?>
636 <tr>
637 <th class="filter-plugins-name" rowspan="2"><?php esc_html_e('Plugins', 'plf'); ?></th>
638 <?php if($urlnum > 0) { ?>
639 <th class="filter-type urlfilter" colspan="<?php echo esc_html($urlnum); ?>" style="font-weight:bold; font-size:smaller;"><?php esc_html_e('URL Group Filter', 'plf'); ?></th>
640 <?php } ?>
641 <th class="filter-type filter-tmpl" colspan="3" style="font-weight:bold; font-size:smaller;"><?php esc_html_e('Page Type Filter', 'plf'); ?></th>
642 </tr>
643 <tr>
644 <?php //Addon URL filter group key
645 if($urlnum > 0) {
646 foreach ( $groupkeys as $v) {
647 $_flt = (method_exists('Plf_filter', 'get_slug_filter'))? Plf_filter::get_slug_filter( $v ) : array();
648 $hint = '';
649 foreach ($_flt as $_v) {
650 $hint .= '[' . $_v['slug'] . '] ' . $_v['summary'] . PHP_EOL;
651
652 if((int)$_v['targetpage'] === 1) {
653 $post_type = (!empty($_v['post_type']))? $_v['post_type'] : '';
654 $taxonomy = '';
655 if(!empty($_v['taxonomies']) && !empty($_v['term'])){
656 $taxonomy = " : {$_v['taxonomies']}({$_v['term']})";
657 }
658 if(!empty($post_type)){
659 $hint .= 'Singular (' . $post_type . ')' . $taxonomy . PHP_EOL;
660 } else {
661 $hint .= 'Singular ' . $taxonomy . PHP_EOL;
662 }
663 } elseif((int)$_v['targetpage'] === 2) {
664 if(!empty($_v['ajax_action'])){
665 $hint .= 'Ajax request (' . $_v['ajax_action'] . ')' . PHP_EOL;
666 } else {
667 $hint .= 'Ajax request' . PHP_EOL;
668 }
669 }
670
671 $hint .= 'url filter : ';
672 $urlkey = (!empty($_v['url_path']))? array_filter( array_map("trim", explode(PHP_EOL, $_v['url_path']))) : array();
673 if(!empty($urlkey)){
674 foreach ($urlkey as $key) {
675 $hint .= $key . ' ';
676 }
677 }
678 $urlkey = (!empty($_v['url_q_and']))? array_filter( array_map("trim", explode(PHP_EOL, $_v['url_q_and']))) : array();
679 if(!empty($urlkey)){
680 foreach ($urlkey as $key) {
681 $hint .= ' AND ' . $key;
682 }
683 }
684 $urlkey = (!empty($filter['url_q_not']))? array_filter( array_map("trim", explode(PHP_EOL, $filter['url_q_not']))) : array();
685 if(!empty($urlkey)){
686 foreach ($urlkey as $key) {
687 $hint .= ' NOT ' . $key;
688 }
689 }
690 $hint .= PHP_EOL . PHP_EOL;
691 }
692 echo '<th class="filter-type urlfilter"><span title="' . esc_html($hint) . '" style="font-size:smaller">' . esc_html($v) . '</span></th>';
693 }
694 } ?>
695 <th class="filter-type filter-none"><span style="font-size:smaller"><?php esc_html_e('Normal', 'plf'); ?></span></th>
696 <th class="filter-type filter-admin"><span style="font-size:smaller"><?php esc_html_e('Admin Type', 'plf'); ?></span></th>
697 <th class="filter-type filter-tmpl"><span style="font-size:smaller"><?php esc_html_e('Page Type', 'plf'); ?></span></th>
698 </tr>
699 </thead>
700 <tbody class="plugins-table-body">
701 <?php
702 //plugins filter registoration table
703 $plist = array();
704 foreach ( $plugins as $p_key => $val ) {
705 $name = self::pluginkey_to_name($p_key);
706 if(!empty($name))
707 $plist[$p_key] = '';
708 }
709 $jlist = $clist = array();
710 foreach ( $plist as $p_key => $val ) {
711 if(strpos($p_key, 'jetpack_module/') !== false){
712 $jlist[$p_key] = $plist[$p_key];
713 unset($plist[$p_key]);
714 }
715 else if(strpos($p_key, 'celtispack_module/') !== false){
716 $clist[$p_key] = $plist[$p_key];
717 unset($plist[$p_key]);
718 }
719 }
720 //Addon URL filter group key
721 $chklist = array();
722 if($urlnum > 0) {
723 foreach ( $groupkeys as $key) {
724 $chklist[] = $key;
725 }
726 }
727
728 foreach ( $plist as $p_key => $val ) {
729 $modules = array();
730 if(strpos($p_key, 'jetpack/') !== false)
731 $modules = $jlist;
732 else if(strpos($p_key, 'celtispack/') !== false)
733 $modules = $clist;
734 else
735 $this->plfregist_item($p_key, $chklist, $filter);
736 if(!empty($modules)){
737 echo '<input type="hidden" name="plfregist[' . esc_html($p_key) . ']" value="_pagefilter">';
738 foreach ( $modules as $m_key => $val) {
739 $this->plfregist_item($m_key, $chklist, $filter);
740 }
741 }
742 }
743 ?>
744 </tbody>
745 </table>
746 </div>
747 <p></p>
748 <div class="grid-row">
749 <div class="filter-description">
750 <p><strong>[ <?php esc_html_e('Page Type Filter', 'plf'); ?> ]</strong></p>
751 <?php self::decode_safe_tag_e( 'strong', esc_html__('<strong>Normal</strong> - Exclude plugin from Page Type filter', 'plf')); ?><br />
752 <?php self::decode_safe_tag_e( 'strong', esc_html__('<strong>Admin Type</strong> - If you only use plugins for Admin pages.', 'plf')); ?><br />
753 <?php self::decode_safe_tag_e( 'strong', esc_html__('<strong>Page Type</strong> - If you want to activate or deactivate plugins for each Page Type and Single page.', 'plf')); ?>
754 <p>
755 <?php
756 $checked = (!empty(self::$filter['admin_bar']))? self::$filter['admin_bar'] : false;
757 echo '<span class="admin-bar-option"><label><input type="checkbox" name="plf_option[admin_bar]" value="1" ' . checked( $checked, 1, false ) . '/> ' . esc_html__('Add a link to admin bar for displaying the plugins filtered status', 'plf') . '</label></span>';
758 ?>
759 </p>
760 <p><?php esc_html_e('* Plugins with `Page Type Filter` selected are blocked, but you can Activate it for various Page type in the `Page Type Activation` and Single Page setting.', 'plf'); ?></p>
761 <div class="ckbox-list">
762 <p><?php self::decode_safe_tag_e( 'strong', esc_html__('<strong>Exclude Post Format Type</strong> - Choose Post Format Type you are not using. To exclude from Page Type item subject.', 'plf')); ?></p>
763 <div>
764 <?php
765 $pformat = array('image', 'gallery', 'video', 'audio', 'aside', 'status', 'quote', 'link', 'chat' );
766 foreach ( $pformat as $type ) {
767 $check = !empty(self::$filter['exclude'][$type])? true : false;
768 ?>
769 <label><input type="checkbox" name="<?php echo esc_html("plf_option[exclude][$type]"); ?>" <?php checked($check); ?>/> <span><?php echo esc_html($type); ?></span></label>
770 <?php
771 }
772 ?>
773 </div>
774 </div>
775 <div class="ckbox-list">
776 <p><?php self::decode_safe_tag_e( 'strong', esc_html__('<strong>Hide Single Post Filters</strong> - Hide single-post filter settings box for custom post type edit page', 'plf')); ?></p>
777 <div>
778 <?php
779 $post_types = get_post_types( array('_builtin' => false), 'objects' );
780 if(!empty($post_types)){
781 foreach ( $post_types as $type ) {
782 $check = !empty(self::$filter['hidecpt'][$type->name])? true : false;
783 ?>
784 <label><input type="checkbox" name="<?php echo esc_html("plf_option[hidecpt][$type->name]"); ?>" <?php checked($check); ?>/> <span><?php echo esc_html("{$type->labels->name} ({$type->name})"); ?></span></label>
785 <?php
786 }
787 } else {
788 esc_html_e('Custom post type not defined', 'plf');
789 }
790 ?>
791 </div>
792 </div>
793 <p><strong>[ <?php esc_html_e('Post Language Locale', 'plf'); ?> ]</strong></p>
794 <p><?php esc_html_e('A very simple multilingual feature that uses MO translation files for the selected locale per Post/Page editing screen.','plf'); ?></p>
795 <?php
796 $checked = (!empty(self::$filter['language']))? self::$filter['language'] : false;
797 echo '<div class="option-item"><label><input type="checkbox" name="plf_option[language]" value="1" ' . checked( $checked, 1, false ) . '/> ' . esc_html__('Language switching per post', 'plf') . '</label></div>';
798 ?>
799
800 <?php //開発モード限定機能
801 $devmode = wp_get_development_mode();
802 if (!empty($devmode)) { ?>
803 <p><strong>[ <?php esc_html_e('Ajax acceleration filter (Features for plugin developers)', 'plf'); ?> ]</strong></p>
804 <p><?php esc_html_e('If you are implementing Ajax requests in your plugin development, you can deactivate unnecessary plugins and speed up Ajax by setting the plugin slugs to be activated to `_ajax_plf` in the request data.','plf'); ?></p>
805 <?php
806 $checked = (!empty(self::$filter['ajax_accelfilter']))? self::$filter['ajax_accelfilter'] : false;
807 echo '<div class="option-item"><label><input type="checkbox" name="plf_option[ajax_accelfilter]" value="1" ' . checked( $checked, 1, false ) . '/> ' . esc_html__('Ajax acceleration filter', 'plf') . '</label></div>';
808 } ?>
809 </div>
810 <div class="side-info">
811 <?php if(! is_plugin_active('plugin-load-filter-addon/plugin-load-filter-addon.php')){ ?>
812 <div style="background-color: #f0fff0; border:1px solid #70c370; padding:4px 20px; margin: 10px 0;" >
813 <p><strong><?php esc_html_e('Introduction of Addon', 'plf'); ?></strong></p>
814 <p><?php esc_html_e('Thank you for using Plugin Load Filter. We offer URL filtering as Addon. Please consider using Addon!', 'plf'); ?></p>
815 <p><?php esc_html_e('See more information ', 'plf'); ?><a target="_blank" rel="noopener" href="https://celtislab.net/en/wp-plugin-load-filter-addon/"> Plugin Load Filter Addon</a></p>
816 </div>
817 <?php } ?>
818 <?php if(! is_plugin_active('realtime-img-optimizer/realtime-img-optimizer.php')){ ?>
819 <div style="background-color: #f0fff0; border:1px solid #70c370; padding:4px 20px; margin: 10px 0;" >
820 <p><strong><?php esc_html_e('Introduction of Realtime Image Optimizer', 'plf'); ?></strong></p>
821 <p><?php esc_html_e('We sell Image Optimization plugin. Reduce and speed up data size by converting to WebP / AVIF.', 'plf'); ?></p>
822 <p><?php esc_html_e('See more information ', 'plf'); ?><a target="_blank" rel="noopener" href="https://celtislab.net/en/wp-realtime-image-optimizer/"> Realtime Image Optimizer</a></p>
823 </div>
824 <?php } ?>
825 <?php if(! is_plugin_active('celtis-diff-monitor-backups/celtis-diff-monitor-backups.php')){ ?>
826 <div style="background-color: #f0fff0; border:1px solid #70c370; padding:4px 20px; margin: 10px 0;" >
827 <p><strong><?php esc_html_e('Introduction of DB/File Diff Monitor and Backups', 'plf'); ?></strong></p>
828 <p><?php esc_html_e('A security and backup plugin that detects unauthorized changes and minimizes data loss with rapid recovery.', 'plf'); ?></p>
829 <p><?php esc_html_e('See more information ', 'plf'); ?><a target="_blank" rel="noopener" href="https://celtislab.net/en/celtis-diff-monitor-backups/"> DB/File Diff Monitor and Backups</a></p>
830 </div>
831 <?php } ?>
832 </div>
833 </div>
834 <?php
835 }
836
837 //Activate plugins select from Page Filter
838 public function _plfactive_checkbox_row($p_key, $select_cvplugins, $chklist, $filter) {
839
840 $selplugins = array_map("trim", explode(',', $select_cvplugins));
841 $devlist = array('desktop','mobile');
842 if(in_array( $p_key, $selplugins )){
843 $p_name = self::pluginkey_to_name($p_key);
844 echo '<tr><td class="plugins-name">' . esc_html($p_name) . '</td>';
845 foreach($devlist as $devtype){
846 $name = "plfactive[$devtype][$p_key]";
847 $checked = (empty($filter['group'][$devtype]['plugins']) || false === strpos($filter['group'][$devtype]['plugins'], $p_key))? false : true;
848 echo '<td class="device-type"><label><input type="checkbox" name="' . esc_html($name) . '" class="altcheckbox" value="1" ' . checked( $checked, 1, false ). '/> <span class="dashicons dashicons-yes"></span></label></td>';
849 }
850 foreach($chklist as $pgtype){
851 $name = "plfactive[$pgtype][$p_key]";
852 $checked = (empty($filter['group'][$pgtype]['plugins']) || false === strpos($filter['group'][$pgtype]['plugins'], $p_key))? false : true;
853 echo '<td class="ckbox-type"><label><input type="checkbox" name="' . esc_html($name) . '" class="altcheckbox" value="1" ' . checked( $checked, 1, false ). '/> <span class="dashicons dashicons-admin-plugins"></span></label></td>';
854 }
855 echo "</tr>";
856 }
857 }
858
859 public function plfactive_table($plugins, $select_cvplugins, $filter) {
860 if(empty($select_cvplugins))
861 return;
862
863 ?>
864 <div id="wrap_activation-table">
865 <table id="activation-table" class="widefat">
866 <thead>
867 <tr><th class="plugins-name"><?php esc_html_e('Plugins', 'plf'); ?></th>
868 <th class="device-type"><span title="<?php esc_html_e('Desktop Device', 'plf'); ?>" class="dashicons dashicons-desktop"></span><br /><span style="font-size:xx-small">Desktop</span></th>
869 <th class="device-type"><span title="<?php esc_html_e('Mobile Device', 'plf'); ?>" class="dashicons dashicons-smartphone"></span><br /><span style="font-size:xx-small">Mobile</span></th>
870 <th class="ckbox-type"><span title="<?php esc_html_e('Home/Front-page', 'plf'); ?>" class="dashicons dashicons-admin-home"></span><br /><span style="font-size:xx-small">Home</span></th>
871 <th class="ckbox-type"><span title="<?php esc_html_e('Archive page', 'plf'); ?>" class="dashicons dashicons-list-view"></span><br /><span style="font-size:xx-small">Archive</span></th>
872 <th class="ckbox-type"><span title="<?php esc_html_e('Search page', 'plf'); ?>" class="dashicons dashicons-search"></span><br /><span style="font-size:xx-small">Search</span></th>
873 <th class="ckbox-type"><span title="<?php esc_html_e('Attachment page', 'plf'); ?>" class="dashicons dashicons-media-default"></span><br /><span style="font-size:xx-small">Attach</span></th>
874 <th class="ckbox-type"><span title="<?php esc_html_e('Page', 'plf'); ?>" class="dashicons dashicons-admin-page"></span><br /><span style="font-size:xx-small">Page</span></th>
875 <th class="ckbox-type pformat"><span title="<?php esc_html_e('Post : ', 'plf'); esc_html_e('Standard', 'plf'); ?>" class="dashicons dashicons-admin-post"></span><br /><span style="font-size:xx-small">Post</span></th>
876 <?php
877 $pformat = array('image', 'gallery', 'video', 'audio', 'aside', 'status', 'quote', 'link', 'chat' );
878 $exclude = array();
879 if(!empty($filter['exclude'])){
880 foreach ( $filter['exclude'] as $type => $v) {
881 if(!empty($v)){
882 $exclude[] = $type;
883 }
884 }
885 }
886 foreach ( $pformat as $type) {
887 if(!in_array($type, $exclude)){
888 $title = esc_html__('Post : ', 'plf') . $type;
889 $icon = ($type === "link")? "dashicons-admin-links" : "dashicons-format-$type";
890 echo '<th class="ckbox-type pformat"><span title="' . esc_html($title) . '" class="dashicons ' . esc_html($icon) .'"></span><br /><span style="font-size:xx-small">' . esc_html($type) .'</span></th>';
891 }
892 }
893 if(function_exists('is_embed')){
894 $title = esc_html__('WordPress Embed Content Card (API)', 'plf');
895 echo '<th class="ckbox-type tmpl-embed"><span title="' . esc_html($title) . '" style="font-size:xx-small">Embed Content</span></th>';
896 }
897 $post_types = get_post_types( array('public' => true, '_builtin' => false) );
898 foreach ( $post_types as $post_type ) {
899 if(!empty($post_type)){
900 $title = esc_html__('Custom Post : ', 'plf') . $post_type;
901 echo '<th class="ckbox-type tmpl-custom"><span title="' . esc_html($title) . '" style="font-size:xx-small">' . esc_html($post_type) . '</span></th>';
902 }
903 }
904 ?>
905 </tr>
906 </thead>
907 <tbody class="plugins-table-body">
908 <?php
909 $nplugins = $jmodules = $cmodules = $allmodule = array();
910 foreach ( $plugins as $p_key => $p_data ) {
911 $p_name = self::pluginkey_to_name($p_key);
912 if(empty($p_name))
913 continue;
914 if(strpos($p_key, 'jetpack_module/') !== false)
915 $jmodules[] = $p_key;
916 else if(strpos($p_key, 'celtispack_module/') !== false)
917 $cmodules[] = $p_key;
918 else
919 $nplugins[] = $p_key;
920 }
921 $chklist = array('home', 'archive', 'search', 'attachment', 'page', 'post');
922 foreach ( $pformat as $type) {
923 if(!in_array($type, $exclude)){
924 $chklist[] = "post-$type";
925 }
926 }
927 if(function_exists('is_embed')){
928 $chklist[] = 'content-card';
929 }
930 $post_types = get_post_types( array('public' => true, '_builtin' => false) );
931 foreach ( $post_types as $post_type ) {
932 $chklist[] = $post_type;
933 }
934 foreach ( $nplugins as $p_key ) {
935 if(strpos($p_key, 'jetpack/') !== false){
936 foreach ( $jmodules as $p_key ) {
937 $this->_plfactive_checkbox_row($p_key, $select_cvplugins, $chklist, $filter);
938 }
939 }
940 else if(strpos($p_key, 'celtispack/') !== false){
941 foreach ( $cmodules as $p_key ) {
942 $this->_plfactive_checkbox_row($p_key, $select_cvplugins, $chklist, $filter);
943 }
944 }
945 else {
946 $this->_plfactive_checkbox_row($p_key, $select_cvplugins, $chklist, $filter);
947 }
948 }
949 ?>
950 </tbody>
951 </table>
952 </div>
953 <?php
954 }
955
956 //Option Setting Form Display
957 public function plf_option_page() {
958 $clear_dialog = __('Plugin Load Filter Settings\nClick OK to clear it.', 'plf');
959 ?>
960 <h2><?php esc_html_e('Plugin Load Filter Settings', 'plf'); ?></h2>
961 <p></p>
962 <div id="plf-setting-tabs">
963 <ul>
964 <li><a href="#plf-registration-tab" ><?php esc_html_e('Filter Registration', 'plf'); ?></a></li>
965 <li><a href="#plf-activation-tab" ><?php esc_html_e('Page Type Activation', 'plf'); ?></a></li>
966 </ul>
967 <div id="plf-registration-tab" style="display : none;">
968 <form method="post" autocomplete="off">
969 <?php wp_nonce_field( 'plugin_load_filter'); ?>
970 <?php $this->plfregist_table(self::$plugins_inf, self::$filter); ?>
971 <p class="submit">
972 <input type="submit" class="button-primary" name="clear_regist_filter" value="<?php esc_html_e('Clear', 'plf'); ?>" onclick="return confirm('<?php echo esc_html($clear_dialog); ?>')" />&nbsp;&nbsp;&nbsp;
973 <input type="submit" class="button-primary" name="edit_regist_filter" value="<?php esc_html_e('Filter Entry &raquo;', 'plf'); ?>" />
974 </p>
975 </form>
976 </div>
977 <div id="plf-activation-tab" style="display : none;">
978 <form method="post" autocomplete="off">
979 <?php wp_nonce_field( 'plugin_load_filter'); ?>
980 <?php
981 $pgfilter = (!empty(self::$filter['_pagefilter']['plugins']))? self::$filter['_pagefilter']['plugins'] : array();
982 if(!empty($pgfilter)){
983 $this->plfactive_table(self::$plugins_inf, $pgfilter, self::$filter);
984 ?>
985 <br />
986 <p><?php
987 self::decode_safe_tag_e( 'span', esc_html__('Select plugins to be activated for each page type by clicking on <span class="dashicons dashicons-admin-plugins"></span> mark from "page type filter" registered plugins.', 'plf'));
988 ?><br />
989 <?php esc_html_e('You can also select plugins to activate from Post/Page content editing screen.', 'plf') ?>
990 </p>
991 <p class="submit">
992 <input type="submit" class="button-primary" name="clear_activate_page_filter" value="<?php esc_html_e('Clear', 'plf'); ?>" onclick="return confirm('<?php echo esc_html($clear_dialog); ?>')" />&nbsp;&nbsp;&nbsp;
993 <input type="submit" class="button-primary" name="edit_activate_page_filter" value="<?php esc_html_e('Activate Plugin Entry &raquo;', 'plf'); ?>" />
994 </p>
995 <?php
996 } else {
997 ?>
998 <br />
999 <p><span style="color: #ff0000;"><?php esc_html_e('Page Filter is not registered', 'plf') ?></span></p>
1000 <?php
1001 }
1002 ?>
1003 </form>
1004 </div>
1005 </div>
1006 <?php
1007 }
1008
1009 /***************************************************************************
1010 * Meta box
1011 * Individual of the plug-in filter meta box for Post/Page/CustomPost
1012 **************************************************************************/
1013 function load_meta_boxes( $post_type, $post ) {
1014 if ( current_user_can('activate_plugins', $post->ID) ) {
1015 $type = get_post_type();
1016 $post_types = get_post_types( array('public' => true, '_builtin' => true) );
1017 if(!in_array($type, $post_types)){
1018 $custom_types = get_post_types( array('_builtin' => false) );
1019 if(!in_array($type, $custom_types) || !empty(self::$filter['hidecpt'][$type])){
1020 return;
1021 }
1022 }
1023 add_meta_box( 'pluginfilterdiv', esc_html__( 'Plugin Load Filter', 'plf' ), array(&$this, 'plf_meta_box'), null, 'side' );
1024 add_action( 'admin_footer', array(&$this, 'plf_meta_script' ));
1025 }
1026 }
1027
1028 //Plugin pagefilter Selected Checkbox (plugin and modules list)
1029 // $p_key
1030 // $select_cvplugins : csv string : pagefilter selected plugins
1031 // $checked_arcvplugins : array csv string : ['desktop']=desktop enable plugins, ['mobile']=mobile enable plugins
1032 function _pagefilter_plugins_checklist( $p_key, $select_cvplugins, $checked_arcvplugins ) {
1033
1034 $html = '';
1035 $selplugins = array_map("trim", explode(',', $select_cvplugins));
1036 $device['desktop'] = $checked_arcvplugins['desktop'];
1037 $device['mobile'] = $checked_arcvplugins['mobile'];
1038 $devlist = array('desktop','mobile');
1039 if(in_array( $p_key, $selplugins )){
1040 $p_name = self::pluginkey_to_name($p_key);
1041 $html .= "<tr><td class='plugins-name'>$p_name</td>";
1042 foreach($devlist as $devtype){
1043 $name = "plf_option[$devtype][$p_key]";
1044 $checked = (empty($device[$devtype]) || false === strpos($device[$devtype], $p_key))? false : true;
1045 $html .= '<td class="device-type ' . esc_html($devtype) . '"><label><input type="checkbox" name="' . esc_html($name) . '" class="altcheckbox" value="1" ' . checked( $checked, 1, false ). '/> <span class="dashicons dashicons-yes"></span></label></td>';
1046 }
1047 $html .= "</tr>";
1048 }
1049 return $html;
1050 }
1051
1052 //Plugin pagefilter Selected Checkbox (plugin and modules list)
1053 // $plugins : array : all active plugins
1054 // $select_cvplugins : csv string : pagefilter selected plugins
1055 // $checked_arcvplugins : array csv string : ['desktop']=desktop enable plugins, ['mobile']=mobile enable plugins
1056 function pagefilter_plugins_checklist( $plugins, $select_cvplugins, $checked_arcvplugins ) {
1057
1058 if(empty($select_cvplugins))
1059 return esc_html__('Page Filter is not registered', 'plf');
1060
1061 $html = '<table id="activation-table">';
1062 $html .= '<thead>';
1063 $html .= '<tr><th class="plugins-name">'. esc_html__('Plugins') . '</th>';
1064 $html .= '<th class="device-type"><span title="'. esc_html__('Desktop Device', 'plf'). '" class="dashicons dashicons-desktop"></span><br /><span style="font-size:xx-small">Desktop</span></th>';
1065 $html .= '<th class="device-type"><span title="'. esc_html__('Mobile Device', 'plf'). '" class="dashicons dashicons-smartphone"></span><br /><span style="font-size:xx-small">Mobile</span></th>';
1066 $html .= '</tr>';
1067 $html .= '</thead>';
1068 $html .= '<tbody class="plugins-table-body meta-boxes-plugins-table">';
1069 $nplugins = $jmodules = $cmodules = array();
1070 foreach ( $plugins as $p_key => $p_data ) {
1071 $p_name = self::pluginkey_to_name($p_key);
1072 if(empty($p_name))
1073 continue;
1074 if(strpos($p_key, 'jetpack_module/') !== false)
1075 $jmodules[] = $p_key;
1076 else if(strpos($p_key, 'celtispack_module/') !== false)
1077 $cmodules[] = $p_key;
1078 else
1079 $nplugins[] = $p_key;
1080 }
1081
1082 foreach ( $nplugins as $p_key ) {
1083 if(strpos($p_key, 'jetpack/') !== false){
1084 foreach ( $jmodules as $p_key ) {
1085 $html .= $this->_pagefilter_plugins_checklist( $p_key, $select_cvplugins, $checked_arcvplugins );
1086 }
1087 }
1088 else if(strpos($p_key, 'celtispack/') !== false){
1089 foreach ( $cmodules as $p_key ) {
1090 $html .= $this->_pagefilter_plugins_checklist( $p_key, $select_cvplugins, $checked_arcvplugins );
1091 }
1092 }
1093 else {
1094 $html .= $this->_pagefilter_plugins_checklist( $p_key, $select_cvplugins, $checked_arcvplugins );
1095 }
1096 }
1097 $html .= '</tbody>';
1098 $html .= '</table>';
1099 return $html;
1100 }
1101
1102 //get_locale に加えたフィルターフックを外してサイトのロケールを取得
1103 static function get_site_locale(){
1104 global $locale;
1105 if(class_exists('Plf_filter')){
1106 remove_filter( 'locale', array('Plf_filter', 'post_locale') );
1107 $locale = null;
1108 $site_locale = get_locale();
1109 add_filter( 'locale', array('Plf_filter', 'post_locale') );
1110 } else {
1111 $locale = null;
1112 $site_locale = get_locale();
1113 }
1114 return $site_locale;
1115 }
1116
1117 function plf_meta_box( $post, $box ) {
1118 if(is_object($post)){
1119 $myfilter = get_post_meta( $post->ID, '_plugin_load_filter', true );
1120 //ver2.2.0 for compatibility, set 'plugins' data to 'desktop' and 'mobile'
1121 if(is_array($myfilter) && !empty($myfilter['plugins'])){
1122 $myfilter['desktop'] = $myfilter['plugins'];
1123 $myfilter['mobile'] = $myfilter['plugins'];
1124 unset($myfilter['plugins']);
1125 }
1126 $default = array( 'filter' => 'default', 'desktop' => '', 'mobile' => '');
1127 $option = (!empty($myfilter) && is_array($myfilter))? $myfilter : $default;
1128 $option = wp_parse_args( $option, $default);
1129 $pgfilter = (!empty(self::$filter['_pagefilter']['plugins']))? self::$filter['_pagefilter']['plugins'] : array();
1130 $ajax_nonce = wp_create_nonce( 'plugin_load_filter-' . $post->ID );
1131 $this->plf_css();
1132 ?>
1133 <div id="plugin-filter-select">
1134 <p><?php esc_html_e( 'Plugin filter for Single post', 'plf' ); ?></p>
1135 <label><input type="radio" name="pagefilter" value="default" <?php checked('default', $option['filter']); ?>/><?php esc_html_e('Not Use', 'plf' ); ?></label>
1136 <label><input type="radio" name="pagefilter" value="include" <?php checked('include', $option['filter']); ?>/><?php esc_html_e('Use', 'plf'); ?></label>
1137 <div id="page-filter-stat">
1138 <?php echo wp_kses($this->pagefilter_plugins_checklist( self::$plugins_inf, $pgfilter, $option ), self::get_allowed_tags()); ?>
1139 </div>
1140 <div class="plf-option-info"><?php esc_html_e('Plugin Activate/Deactivate filter for this Post only', 'plf'); ?></div>
1141 <?php
1142 $c_locale = $o_post_id = '';
1143 $languages = array();
1144 $locale_mode = 'style="display:none;"';
1145 if(!empty(self::$filter['language'])){
1146 $languages = get_available_languages();
1147 $site_locale = self::get_site_locale();
1148 //bogo と同じ _locale ポストメタデータ採用
1149 $c_locale = get_post_meta( $post->ID, '_locale', true );
1150 if(empty($c_locale)){
1151 $c_locale = $site_locale;
1152 }
1153 if ( ! in_array( $c_locale, $languages ) ) {
1154 $c_locale = '';
1155 }
1156 $o_post_id = get_post_meta( $post->ID, '_original_post_id', true );
1157 $o_post_id = (is_numeric($o_post_id))? $o_post_id : '';
1158 $locale_mode = '';
1159 }
1160 echo '<p class="hide-if-no-js"><a id="plugin-filter-submit" class="button" href="#pluginfilterdiv" onclick="WPAddPagePluginLoadFilter(\'' . esc_html($ajax_nonce) . '\');return false;" >'. esc_html__('Save') .'</a></p>';
1161 ?>
1162 <hr>
1163 <div id="plf-post-locale-select" <?php echo esc_html($locale_mode); ?>>
1164 <p><?php esc_html_e( 'Language of this post', 'plf' ); ?> <span class="dashicons dashicons-translation" aria-hidden="true"></span></p>
1165 <?php
1166 wp_dropdown_languages(
1167 array(
1168 'name' => 'plf_locale',
1169 'id' => 'plf_locale',
1170 'selected' => $c_locale,
1171 'languages' => $languages,
1172 'show_available_translations' => false,
1173 )
1174 );
1175 ?>
1176 <p><?php esc_html_e( 'Original post ID for hreflang', 'plf' ); ?></p>
1177 <input type="text" id="plf_original_post_id" name="plf_original_post_id" size="8" value="<?php echo esc_html($o_post_id); ?>" />
1178 <div class="hflang-group-edit-lonk">
1179 <?php
1180 $id = (is_numeric($o_post_id))? $o_post_id : $post->ID;
1181 global $wpdb;
1182 $ids = $wpdb->get_row($wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_original_post_id' AND meta_value = %d", $id ), ARRAY_N);
1183 if(is_array($ids)){
1184 if(!in_array((string)$id, $ids)){
1185 $ids[] = (string)$id;
1186 }
1187 if(count($ids) > 1){
1188 foreach ($ids as $v) {
1189 if( $post->ID != $v){
1190 $l = get_post_meta( $v, '_locale', true );
1191 if(empty($l)){
1192 $l = $site_locale;
1193 }
1194 $url = get_edit_post_link( $v );
1195 if(!empty($url)){
1196 echo '<p><a class="edit-post-locale-link" target="_blank" href="' . esc_html($url) .'" rel="external noreferrer noopener">' . esc_html__('Edit Post') . ' (' . esc_html($l) . ') ' . '<span class="dashicons dashicons-external" aria-hidden="true"></span></a></p>';
1197 }
1198 }
1199 }
1200 }
1201 }
1202 ?>
1203 </div>
1204 <div class="plf-option-info"><?php esc_html_e('Use MO translation file for the selected locale. When Original Post ID is registered, posts with the same Original Post ID are treated as `hreflang` metadata group.', 'plf'); ?></div>
1205 <?php echo '<p class="hide-if-no-js"><a id="plugin-filter-submit" class="button" href="#pluginfilterdiv" onclick="WPAddPagePluginLoadFilter(\'' . esc_html($ajax_nonce) . '\');return false;" >'. esc_html__('Save') .'</a></p>'; ?>
1206 </div>
1207 </div>
1208 <?php
1209 }
1210 }
1211
1212 //wp_ajax_plugin_load_filter called function
1213 function plf_ajax_postidfilter() {
1214 if ( isset($_POST['post_id']) ) {
1215 $pid = (int) $_POST['post_id'];
1216 if ( !current_user_can( 'activate_plugins', $pid ) )
1217 wp_die( -1 );
1218 check_ajax_referer( "plugin_load_filter-$pid" );
1219
1220 if(!empty(self::$filter['language'])){
1221 if(isset($_POST['locale'])){
1222 $s_locale = (!empty($_POST['locale']))? sanitize_text_field(wp_unslash($_POST['locale'])) : 'en_US';
1223 $languages = get_available_languages();
1224 $languages[] = 'en_US'; //add WP default locale
1225 if ( in_array( $s_locale, $languages ) ) {
1226 $g_locale = get_post_meta( $pid, '_locale', true );
1227 global $locale;
1228 if(class_exists('Plf_filter')){
1229 remove_filter( 'locale', array('Plf_filter', 'post_locale') );
1230 $locale = null;
1231 $o_locale = get_locale();
1232 add_filter( 'locale', array('Plf_filter', 'post_locale') );
1233 } else {
1234 $locale = null;
1235 $o_locale = get_locale();
1236 }
1237 if($s_locale !== $g_locale){
1238 if($s_locale === $o_locale){
1239 delete_post_meta( $pid, '_locale');
1240 } else {
1241 update_post_meta( $pid, '_locale', $s_locale );
1242 }
1243 }
1244 }
1245 }
1246 if(isset($_POST['original_post_id'])){
1247 if(empty($_POST['original_post_id'])){
1248 delete_post_meta( $pid, '_original_post_id');
1249 } elseif(preg_match( '/([0-9]+)?/', $_POST['original_post_id'], $match )){
1250 $o_id = (int)$match[1];
1251 $post = get_post($o_id);
1252 if(is_object($post)){
1253 $g_id = get_post_meta( $pid, '_original_post_id', true );
1254 if($o_id !== $g_id){
1255 update_post_meta( $pid, '_original_post_id', $o_id );
1256 }
1257 }
1258 }
1259 }
1260 }
1261 $pgfilter = (!empty(self::$filter['_pagefilter']['plugins']))? self::$filter['_pagefilter']['plugins'] : array();
1262 $option["filter"] = (empty($_POST['filter']))? 'default' : sanitize_text_field(wp_unslash($_POST['filter']));
1263 if('default' == $option["filter"]){
1264 delete_post_meta( $pid, '_plugin_load_filter');
1265 } else {
1266 $plugins = array();
1267 $desktop = sanitize_text_field(wp_unslash($_POST['desktop']));
1268 if( preg_match_all('/plf_option\[desktop\]\[(.+?)\]/u', $desktop, $matches)){
1269 if(!empty($matches[1])){
1270 foreach ($matches[1] as $plugin){
1271 $plugins[] = $plugin;
1272 }
1273 $option["desktop"] = implode(",", $plugins);
1274 }
1275 }
1276 $plugins = array();
1277 $mobile = sanitize_text_field(wp_unslash($_POST['mobile']));
1278 if( preg_match_all('/plf_option\[mobile\]\[(.+?)\]/u', $mobile, $matches)){
1279 if(!empty($matches[1])){
1280 foreach ($matches[1] as $plugin){
1281 $plugins[] = $plugin;
1282 }
1283 $option["mobile"] = implode(",", $plugins);
1284 }
1285 }
1286 update_post_meta( $pid, '_plugin_load_filter', $option );
1287 }
1288
1289 $html = $this->pagefilter_plugins_checklist( self::$plugins_inf, $pgfilter, $option );
1290 wp_send_json_success($html);
1291 }
1292 wp_die( 0 );
1293 }
1294
1295 //alternate hreflang meta tag
1296 static function altenate_hreflang() {
1297 if ( is_singular() ) {
1298 global $post, $wpdb;
1299 $pid = $post->ID;
1300 $oid = get_post_meta( $pid, '_original_post_id', true );
1301 $oid = (is_numeric($oid))? $oid : $pid;
1302 $ids = $wpdb->get_row($wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_original_post_id' AND meta_value = %d", $oid ), ARRAY_N);
1303 if(is_array($ids)){
1304 if(!in_array((string)$oid, $ids)){
1305 $ids[] = (string)$oid;
1306 }
1307 if(count($ids) > 1){
1308 $site_locale = self::get_site_locale();
1309 foreach ($ids as $id) {
1310 $l = get_post_meta( $id, '_locale', true );
1311 if(empty($l)){
1312 $l = $site_locale;
1313 }
1314 $url = get_permalink( $id );
1315 echo '<link rel="alternate" hreflang="' . esc_attr($l) . '" href="' . esc_url($url) .'" />' . PHP_EOL;
1316 }
1317 }
1318 }
1319 }
1320 }
1321
1322 /***************************************************************************
1323 * Javascript
1324 **************************************************************************/
1325 function activetab_script() { ?>
1326 <script type='text/javascript' >
1327 /* <![CDATA[ */
1328 var plf_activetab = <?php echo esc_html($this->tab_num); ?>
1329 /* ]]> */
1330 jQuery(document).ready(function ($) {
1331 plf_setting_tabs();
1332 function plf_setting_tabs(){ $('#plf-setting-tabs').tabs({ active:plf_activetab, }); }
1333 });
1334 </script>
1335 <?php }
1336
1337 function plf_meta_script() {
1338 ?>
1339 <script type='text/javascript' >
1340 WPAddPagePluginLoadFilter = function(nonce){
1341 jQuery.ajax({
1342 type: 'POST',
1343 url: ajaxurl,
1344 data: {
1345 action: "plugin_load_filter",
1346 post_id : jQuery( '#post_ID' ).val(),
1347 _ajax_nonce: nonce,
1348 locale: jQuery("select[name='plf_locale']").val(),
1349 original_post_id: jQuery("input[name='plf_original_post_id']").val(),
1350 filter: jQuery("input[name='pagefilter']:checked").val(),
1351 desktop: jQuery('.meta-boxes-plugins-table td.desktop input:checked').map(function(){ return jQuery(this).attr("name"); }).get().join(','),
1352 mobile: jQuery('.meta-boxes-plugins-table td.mobile input:checked').map(function(){ return jQuery(this).attr("name"); }).get().join(','),
1353 },
1354 dataType: 'json',
1355 }).then(
1356 function (response, dataType) {
1357 jQuery('#page-filter-stat').html(response.data);
1358 if(window.confirm('<?php esc_html_e('Plugin Load Filter setting has been updated.\nClick OK to reload the page.', 'plf'); ?>')){
1359 location.reload();
1360 }
1361 },
1362 function () { /* alert("ajax error"); */ }
1363 );
1364 };
1365 </script>
1366 <?php }
1367 }
1368