Plugin Directory

Changeset 3115930


Ignore:
Timestamp:
07/10/2024 11:15:36 PM (17 months ago)
Author:
majick
Message:

trunk release commit

Location:
adminsanity/trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • adminsanity/trunk/adminsanity.php

    r2821022 r3115930  
    55Plugin URI: https://wpmedic.tech/adminsanity/
    66Description: Add Sanity back to your WordPress Admin Area.
    7 Version: 1.0.2
     7Version: 1.0.3
    88Author: Tony Hayes
    99Author URI: https://wpmedic.tech
  • adminsanity/trunk/adminsanity/adminsanity-bar.php

    r2821022 r3115930  
    5959}
    6060
     61// 1.0.3: bug out if on WordPress.Com (custom/no admin bar)
     62if ( defined( 'WPCOMSH_VERSION' ) ) {
     63    return;
     64}
     65
    6166// --- get frontend override setting ---
    6267// 0.9.9: added frontend override setting
    6368if ( !is_admin() ) {
    6469    $frontend = true;
    65     // 1.0.1: fix to frontent constant (remove CYCLER_)
     70    // 1.0.1: fix to frontend constant (remove CYCLER_)
    6671    if ( defined( 'ADMINSANITY_BAR_FRONTEND' ) ) {
    6772        $frontend = (bool) ADMINSANITY_BAR_FRONTEND;
     
    8691// 1.0.1: use return instead of function wrapper
    8792if ( !function_exists( 'adminsanity_bar_default' ) ) {
     93
     94// note: unlike menu/notices, loader is not needed for scripts/styles
     95// as they are already hooked to admin bar rendering actions
    8896
    8997
     
    156164// Current Screen Fix
    157165// ------------------
    158 // since admin_bar_init is hooked to admin_init, current screen object is not loaded
     166// since admin_bar_init is hooked to admin_init, current screen object is not yet loaded
    159167// which gives current_screen->base property not exists errors in wp_admin_bar_edit_menu (/wp-includes/admin-bar.php)
    160168// ...so this duplicates admin.php current screen initialization to fix that (yeesh)
     
    171179    $current_screen = get_current_screen();
    172180    if ( $adminsanity['bar-debug'] ) {
    173         echo '<span id="current-screen-test" style="display:none;">Current Screen A:' . esc_html( print_r( $current_screen, true ) ) . '</span>' . "\n";
     181        echo '<span class="current-screen-test" style="display:none;">Current Screen A:' . esc_html( print_r( $current_screen, true ) ) . '</span>' . "\n";
    174182    }
    175183    if ( !is_object( $current_screen ) || !property_exists( $current_screen, 'base' ) ) {
    176         global $pagenow;
     184       
     185        global $pagenow, $page_hook, $typenow;
     186        // 1.0.3: fix to set global for plugin_page and hook_suffix ?
     187        // global $plugin_page, $hook_suffix;
    177188        if ( isset( $_GET['page'] ) ) {
    178189            // 1.0.0: use sanitize_title on GET value
     
    192203            $typenow = '';
    193204        }
     205
    194206        if ( isset( $plugin_page ) ) {
    195207            if ( !empty( $typenow ) ) {
     
    198210                $the_parent = $pagenow;
    199211            }
    200             if ( ! $page_hook = get_plugin_page_hook( $plugin_page, $the_parent ) ) {
     212            if ( !$page_hook = get_plugin_page_hook( $plugin_page, $the_parent ) ) {
    201213                $page_hook = get_plugin_page_hook( $plugin_page, $plugin_page );
    202214            }
    203215            unset( $the_parent );
    204216        }
     217
    205218        $hook_suffix = '';
    206219        if ( isset( $page_hook ) ) {
     
    212225        }
    213226
     227        if ( $adminsanity['bar-debug'] ) {
     228            echo '<span style="display:none;">Hook Suffix: ' . $hook_suffix . '</span>' . "\n";
     229            echo '<span style="display:none;">Pagenow: ' . $pagenow . '</span>' . "\n";
     230            echo '<span style="display:none;">Plugin Page: ' . $plugin_page . '</span>' . "\n";
     231            echo '<span style="display:none;">Page Hook: ' . $page_hook . '</span>' . "\n";
     232        }
     233   
    214234        // --- set current screen ---
    215235        // we cannot use function set_current_screen directly as this calls set_current_screen action
     
    218238        // set_current_screen( $pagenow );
    219239        // so instead we duplicate function WP_Screen->set_current_screen but without firing the action
    220         global $current_screen, $taxnow, $typenow, $post;
    221         $current_screen = WP_Screen::get( $pagenow );
    222         $taxnow = $current_screen->taxonomy;
    223         $typenow = $current_screen->post_type;
     240        global $current_screen; // $taxnow, $typenow;
     241        $current_screen = WP_Screen::get( $hook_suffix );
     242        // 1.0.3: disabled these as causing some template editor problems
     243        // $taxnow = $current_screen->taxonomy;
     244        // $typenow = $current_screen->post_type;
     245
     246        if ( $adminsanity['bar-debug'] ) {
     247            echo '<span style="display:none;">Taxonomy: ' . $current_screen->taxonomy . '</span>' . "\n";
     248            echo '<span style="display:none;">Post Type: ' . $current_screen->post_type . '</span>' . "\n";
     249        }
    224250
    225251        // 1.0.2: fix for undefined post->post_type, also in wp_admin_bar_edit_menu
    226252        // (base is now set, but post object may not yet be set on post edit pages)
    227253        if ( 'post' == $current_screen->base ) {
     254            global $post;
    228255            $post = get_post();
    229256            if ( !is_object( $post ) && isset( $_REQUEST['post'] ) ) {
     
    233260           
    234261    }
     262
    235263    if ( $adminsanity['bar-debug'] ) {
    236         $current_screen = get_current_screen();
    237         $post = get_post();
    238         echo '<span id="current-screen-test" style="display:none;">Current Screen B: ' . esc_html( print_r( $current_screen, true ) ) .  '</span>' . "\n";
     264        // $current_screen = get_current_screen();
     265        echo '<span class="current-screen-test" style="display:none;">Current Screen B: ' . esc_html( print_r( $current_screen, true ) ) .  '</span>' . "\n";
    239266    }
    240267}
  • adminsanity/trunk/adminsanity/adminsanity-menu.php

    r2821022 r3115930  
    6767// --- allow for use as an mu-plugin ---
    6868// 0.9.9: attempt to prevent double load conflicts
    69 if ( !function_exists( 'adminsanity_menu_store_default' ) ) {
     69if ( !function_exists( 'adminsanity_menu_loader' ) ) {
     70
     71// ------------------
     72// Menu Loader Action
     73// ------------------
     74// 1.0.3: added loader action to avoid block editor conflicts
     75add_action( 'admin_menu', 'adminsanity_menu_loader', 9 );
     76function adminsanity_menu_loader() {
     77
     78    // --- check for block editor or gutenberg plugin page ---
     79    if ( function_exists( 'get_current_screen' ) ) {
     80        $current_screen = get_current_screen();
     81        if ( is_object( $current_screen ) && method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
     82            return;
     83        }
     84    } elseif ( function_exists( 'is_gutenberg_page' ) && is_gutenberg_page() ) {
     85        return;
     86    }
     87
     88    // 1.0.3: enqueue scripts/styles only if admin_menu action called
     89    add_action( 'admin_footer', 'adminsanity_menu_scripts', 99 );
     90    add_action( 'admin_print_styles', 'adminsanity_menu_styles');
     91
     92    // 1.0.3: custom menu order only if admin menu action called
     93    add_action( 'custom_menu_order', '__return_true', 11 );
     94    add_filter( 'menu_order', 'adminsanity_menu_split_order', 20 );
     95   
     96}
    7097
    7198// ------------------------
     
    76103add_action( '_admin_menu', 'adminsanity_menu_store_default', 0 );
    77104function adminsanity_menu_store_default() {
    78     global $menu, $submenu, $adminsanity;
     105    global $adminsanity, $menu, $submenu;
    79106    $adminsanity['default_menu'] = $menu;
    80107    $adminsanity['default_submenu'] = $submenu;
     
    84111// Ordered Split Admin Menu
    85112// ------------------------
    86 add_action( 'custom_menu_order', '__return_true', 11 );
    87 add_filter( 'menu_order', 'adminsanity_menu_split_order', 20 );
    88113function adminsanity_menu_split_order( $menu_order ) {
    89114
     
    191216    // -----------------
    192217
     218    // --- filter menu items to move to top ---
     219    // 1.0.3: added for top menu items (above mega menus)
     220    $top = apply_filters( 'adminsanity_menu_top_positions', array() );
     221
     222    // --- filter menu items whose position to keep ---
     223    $keep = apply_filters( 'adminsanity_menu_keep_positions', array() );
     224
    193225    // --- set empty split menu arrays ---
    194     $menua = $menua2 = $menub = $menuc = array();
     226    $menutop = $menua = $menua2 = $menub = $menuc = array();
    195227
    196228    // --- loop the menu items ---
     
    203235        }
    204236
    205         // 0.9.6: remove some separators from menu order temporarily
    206         // 0.9.6: check for explicit content items for menu a
    207         $separators = array( 'separator1', 'separator2', 'separator-last' );
    208         $contentitems = array( 'upload.php', 'link-manager.php', 'edit-comments.php' );
    209         if ( $item[2] == 'separator1' ) {
    210             $separator1 = array( $i => 'separator1' );
    211         } elseif ( !in_array( $item[2], $separators ) ) {
    212             if ( ( 'index.php' == $item[2] ) || ( strpos( $item[2], 'edit.php' ) === 0 ) ) {
    213                 $menua[$i] = $item[2];
    214             } elseif ( in_array( $item[2], $contentitems ) ) {
    215                 $menua2[$i] = $item[2];
    216             } elseif ( $item[2] == 'options.php' ) {
    217                 $menub[$i] = $item[2];
    218             } elseif ( !$found ) {
    219                 $menuc[$i] = $item[2];
    220             } else {
    221                 $menub[$i] = $item[2];
    222             }
     237        // 1.0.3: check for top menu position Items
     238        if ( in_array( $item[2], $top ) ) {
     239            $menutop[] = $item[2];
     240        } else {
     241
     242            // 0.9.6: remove some separators from menu order temporarily
     243            // 0.9.6: check for explicit content items for menu a
     244            $separators = array( 'separator1', 'separator2', 'separator-last' );
     245            $contentitems = array( 'upload.php', 'link-manager.php', 'edit-comments.php' );
     246            if ( $item[2] == 'separator1' ) {
     247                $separator1 = array( $i => 'separator1' );
     248            } elseif ( !in_array( $item[2], $separators ) ) {
     249                if ( ( 'index.php' == $item[2] ) || ( strpos( $item[2], 'edit.php' ) === 0 ) ) {
     250                    $menua[$i] = $item[2];
     251                } elseif ( in_array( $item[2], $contentitems ) ) {
     252                    $menua2[$i] = $item[2];
     253                } elseif ( $item[2] == 'options.php' ) {
     254                    $menub[$i] = $item[2];
     255                } elseif ( !$found ) {
     256                    $menuc[$i] = $item[2];
     257                } else {
     258                    $menub[$i] = $item[2];
     259                }
     260            }
     261
    223262        }
    224263    }
     
    229268    }
    230269    unset( $menua2 );
    231 
    232     // --- filter menu items whose position to keep ---
    233     $keep = apply_filters( 'adminsanity_menu_keep_positions', array() );
    234270
    235271    // --- exception - move Settings item to top of section! ---
     
    315351    if ( isset( $_GET['as-debug'] ) && in_array( $_GET['as-debug'], array( 'all', 'menu' ) ) ) {
    316352        echo '<span style="display:none;">[AdminSanity]';
    317         echo 'Menu Items A: ' . esc_html( print_r( $menua_keep, true ) ) . "\n";
    318         echo 'Menu Items B: ' . esc_html( print_r( $menub_keep, true ) ) . "\n";
    319         echo 'Menu Items C: ' . esc_html( print_r( $menuc_keep, true ) ) . "\n";
     353        echo 'Keep Menu Items A: ' . esc_html( print_r( $menua_keep, true ) ) . "\n";
     354        echo 'Keep Menu Items B: ' . esc_html( print_r( $menub_keep, true ) ) . "\n";
     355        echo 'Keep Menu Items C: ' . esc_html( print_r( $menuc_keep, true ) ) . "\n";
    320356        echo '</span>';
    321357    }
     
    333369    }
    334370
     371    // --- debug point ---
     372    // 1.0.3: update debug point output
     373    if ( isset( $_GET['as-debug'] ) && in_array( $_GET['as-debug'], array( 'all', 'menu' ) ) ) {
     374        echo '<span style="display:none;">[AdminSanity]';
     375        echo 'Top Menu Items: ' . esc_html( print_r( $menutop, true ) ) . "\n";
     376        echo 'Menu Items A: ' . esc_html( print_r( $menua, true ) ) . "\n";
     377        echo 'Menu Items B: ' . esc_html( print_r( $menub, true ) ) . "\n";
     378        echo 'Menu Items C: ' . esc_html( print_r( $menuc, true ) ) . "\n";
     379        echo '</span>';
     380    }
     381   
    335382    // --- resort split menus and merge to final menu order ---
    336383    // 0.9.9: use single keyed array for menu items
     
    350397
    351398    // --- debug point ---
    352     // print_r( $menu_items );
     399    // 1.0.3: update debug point output
     400    if ( isset( $_GET['as-debug'] ) && in_array( $_GET['as-debug'], array( 'all', 'menu' ) ) ) {
     401        echo '<span style="display:none;">[AdminSanity]';
     402        echo 'Sorted Menu Items A: ' . esc_html( print_r( $menu_items['a'], true ) ) . "\n";
     403        echo 'Sorted Menu Items B: ' . esc_html( print_r( $menu_items['b'], true ) ) . "\n";
     404        echo 'Sorted Menu Items C: ' . esc_html( print_r( $menu_items['c'], true ) ) . "\n";
     405        echo '</span>';
     406    }
    353407
    354408    // --- get meta menu setting ---
     
    388442    $meta_menu_order = apply_filters( 'adminsanity_menu_meta_order', $meta_menu_order );
    389443    if ( $meta_menu_order && is_array( $meta_menu_order ) ) {
    390         $new_menu_order = array();
     444        // 1.0.3: insert top menu items first
     445        // $new_menu_order = array();
     446        $new_menu_order = $menutop;
    391447        foreach ( $meta_menu_order as $i => $key ) {
    392448            $key = strtolower( $key );
     
    409465        if ( isset( $_GET['as-debug'] ) && in_array( $_GET['as-debug'], array( 'all', 'menu' ) ) ) {
    410466            echo '<span style="display:none;">[AdminSanity] Menu Order:' . esc_html( print_r( $menu_order, true ) ) . '</span>' . "\n";
     467            print_r( get_defined_constants() );
    411468        }
    412469    }
     
    418475// Admin Menu Styles
    419476// -----------------
    420 add_action( 'admin_print_styles', 'adminsanity_menu_styles');
    421477function adminsanity_menu_styles() {
    422478
     
    560616        // 0.9.9 copy other color scheme rules explicitly via javascript
    561617        if ( 'fresh' == $scheme ) {
    562             // #444444
    563             $css .= '.adminsanity-menu-heading {color: #FFF;}' . "\n";
     618            // 1.0.3: set background color explicitly for non-current menu heading
     619            $css .= '.adminsanity-menu-heading {background-color: #1d2327; color: #FFF;}' . "\n";
    564620            $css .= '.adminsanity-menu-wrapper.current-meta .adminsanity-menu-heading {background-color: #0073aa !important;}' . "\n";
    565621        }
     
    620676// 0.9.6: add meta menu creation script
    621677// 0.9.9: add full page expanded menu creation script
    622 add_action( 'admin_footer', 'adminsanity_menu_scripts', 99 );
    623678function adminsanity_menu_scripts() {
    624679
     
    770825        $js .= "var as_expand_menu = '" . esc_js( __( 'Expand Menu', 'adminsanity' ) ) . "'; ";
    771826        $js .= "var as_collapse_menu = '" . esc_js( __( 'Collapse Menu', 'adminsanity' ) ) . "'; ";
    772         $js .= "var as_menu_added = false; " . "\n";
     827        $js .= "var as_menu_added = false; var as_menu_adding = false; var as_delayed_menu = false;" . "\n";
    773828
    774829        // --- add expand menu item to admin menu ---
     
    781836
    782837            // --- create button to expand menu page ---
    783             // TODO: aria-label, aria-expanded ?
    784             // <button type="button" id="expand-button" aria-label="Collapse Main menu" aria-expanded="true"
    785838            $js .= "button = document.createElement('button');
    786             button.setAttribute('type', 'button');
    787             button.setAttribute('id', 'expand-button');" . "\n";
     839            button.setAttribute('id', 'expand-button');
     840            button.setAttribute('aria-label', as_expand_menu);
     841            button.setAttribute('aria-expanded', 'false');" . "\n";
    788842
    789843            // --- button icon ---
     
    806860        // --- add expanded toggle function ---
    807861        $js .= "function adminsanity_menu_toggle() {
    808             if (!as_menu_added) {adminsanity_menu_load();}
     862            if (!as_menu_added) {
     863                if (as_menu_adding) {var as_delayed_menu = setInterval(adminsanity_menu_delayed_toggle, 500); return;}
     864                else {adminsanity_menu_load();}
     865            }
    809866            if (document.getElementById('adminsanity-menu-page').style.display == 'none') {
    810867                document.getElementById('wpbody-content').style.display = 'none';
    811868                document.getElementById('adminsanity-menu-page').style.display = '';
    812869                document.getElementById('adminsanity-toggle-label').innerHTML = as_collapse_menu; /* 'Collapse Menu' */
     870                document.getElementById('expand-button').setAttribute('aria-expanded','true');
    813871                /* if (jQuery('#collapse-menu').attr('aria-expanded') == 'true') {jQuery('#collapse-menu').click();} */
    814872                jQuery('body').addClass('folded'); jQuery('#expand-button').addClass('expanded');
    815                 jQuery('#adminsanity-notices-clear').prependTo('#adminsanity-menu-page');
     873                /* jQuery('#adminsanity-notices-clear').prependTo('#adminsanity-menu-page');
    816874                jQuery('#adminsanity-notices-wrap').prependTo('#adminsanity-menu-page');
    817                 jQuery('#adminsanity-notices-menu').prependTo('#adminsanity-menu-page');
     875                jQuery('#adminsanity-notices-menu').prependTo('#adminsanity-menu-page'); */
    818876            } else {
    819877                document.getElementById('adminsanity-menu-page').style.display = 'none';
     
    822880                /* if (jQuery('#collapse-menu').attr('aria-expanded') == 'false') {jQuery('#collapse-menu').click();} */
    823881                jQuery('body').removeClass('folded'); jQuery('#expand-button').removeClass('expanded');
    824                 jQuery('#adminsanity-notices-wrap').insertAfter('#admin-top-general-notices');
     882                /* jQuery('#adminsanity-notices-wrap').insertAfter('#admin-top-general-notices');
    825883                jQuery('#adminsanity-notices-clear').insertAfter('#admin-top-general-notices');
    826                 jQuery('#adminsanity-notices-menu').insertAfter('#admin-top-general-notices');
    827             }
     884                jQuery('#adminsanity-notices-menu').insertAfter('#admin-top-general-notices'); */
     885            }
     886        }" . "\n";
     887
     888        // --- delayed toggle cycler ---
     889        // 1.0.3: added to catch delayed menu load
     890        $js .= "function adminsanity_menu_delayed_toggle() {
     891            if (as_menu_debug) {console.log('Waiting for expanded menu page to load...');}
     892            if (as_menu_added) {clearInterval(as_delayed_menu); adminsanity_menu_toggle();}
    828893        }" . "\n";
    829894
     
    874939        $js .= "function adminsanity_menu_load() {" . "\n";
    875940
     941            // 1.0.3: added check of menu added/adding flags
     942            $js .= "if (as_menu_added || as_menu_adding) {return;}" . "\n";
     943            $js .= "as_menu_adding = true;" . "\n";
     944
    876945            // --- set menu added flag ---
    877             $js .= "as_menu_added = true;" . "\n";
    878946            $js .= "as_menu_background = jQuery('#adminmenuwrap').css('background-color'); " . "\n";
    879947
    880948            // --- create new page div ---
    881             // TODO: optimize by using jQuery ?
    882             $js .= "pagediv = document.createElement('div');
     949            // 1.0.3: optimized page adding using jQuery
     950            $js .= "menupage = jQuery('<div>').attr('id', 'adminsanity-menu-page').css('display','none');
     951            menupage.prependTo('#wpbody');" . "\n";
     952            // jQuery('#wpbody').append(menupage);" . "\n";
     953            /* $js .= "pagediv = document.createElement('div');
    883954            pagediv.setAttribute('id', 'adminsanity-menu-page');
    884955            pagediv.setAttribute('style', 'display:none;');
    885956            el = document.getElementById('wpbody');
    886             el.insertBefore(pagediv, el.childNodes[0] || null);" . "\n";
     957            el.insertBefore(pagediv, el.childNodes[0] || null);" . "\n"; */
    887958
    888959            // --- dynamic creation of menu wrappers ---
    889             // TODO: optimize menu creation using jQuery
     960            // TODO: optimize menu creation using jQuery ?
    890961            // 0.9.9: loop using key/label javascript array instead of PHP
    891962            // $i = 0;
     
    9921063            // --- fix hover styles ---
    9931064            // (color, background-color)
    994             // note: ## used for exact selector match
     1065            // note: ## is used for exact selector match
    9951066            $selectors = array(
    9961067                '##adminmenu li>a.menu-top:focus',
    9971068                '##adminmenu .wp-submenu a:focus',
    9981069                '##adminmenu .wp-submenu a:hover',
    999 
    10001070                '##adminmenu a:hover',
    10011071                '##adminmenu li.menu-top:hover',
     
    10391109            // }
    10401110
     1111            // 1.0.3: move flag set to end of function
     1112            $js .= "as_menu_added = true; as_menu_adding = false;" . "\n";
     1113
    10411114        // --- close load menu function ---
    10421115        $js .= '}' . "\n";
     
    10471120    // ---------------------
    10481121   
    1049     $readyjs = '';
     1122    // --- open document ready function ---
     1123    $readyjs = "jQuery(document).ready(function() {" . "\n";
    10501124
    10511125    if ( $meta_menus ) {
     
    11001174    if ( $expander ) {
    11011175
    1102         // --- open document ready function ---
    1103         $readyjs .= "jQuery(document).ready(function() {" . "\n";
    1104 
    1105 
    11061176        // --- delayed auto-load of menu ---
    1107         $readyjs .= "setTimeout(adminsanity_menu_load, 1000);" . "\n";
     1177        // 1.0.3: remove autoload of expanded menu for speed (loads fine on click)
     1178        // $readyjs .= "setTimeout(adminsanity_menu_load, 1000);" . "\n";
    11081179
    11091180        // --- clone admin menu item  ---
     
    11111182        $readyjs .= ".attr('id','wp-admin-bar-expand-toggle').attr('class','admin-bar-extra-menu')" . "\n";
    11121183        $readyjs .= ".attr('onclick','adminsanity_menu_toggle();').insertAfter('#wp-admin-bar-menu-toggle');" . "\n";
    1113 
    1114         // --- close document ready functions ---
    1115         $readyjs .= "});" . "\n";
    1116     }
     1184        $readyjs .= "jQuery('#expand-button').on('mouseover', function() {adminsanity_menu_load();});" . "\n";
     1185
     1186        // 1.0.3: test collapse button remains working?
     1187        $readyjs .= "jQuery('#collapse-button').on('click',function(e) {
     1188            console.log(e);
     1189            /* e.preventDefault();
     1190            setTimeout(function() {
     1191                if (jQuery('body').hasClass('folded')) {
     1192                    jQuery('body').removeClass('folded');
     1193                    jQuery('#collapse-button').attr('aria-expanded','true');
     1194                } else {
     1195                    jQuery('body').addClass('folded');
     1196                    jQuery('#collapse-button').attr('aria-expanded','false');
     1197                }
     1198            }, 500); */
     1199        });" . "\n";
     1200
     1201    }
     1202
     1203    // --- close document ready functions ---
     1204    $readyjs .= "});" . "\n";
    11171205
    11181206
     
    13151403}
    13161404
     1405// -------------------------
     1406// Top Menu Positions Filter
     1407// -------------------------
     1408// (array of menu item names to move above megamenus automatically)
     1409add_filter( 'adminsanity_menu_top_positions', 'adminsanity_menu_top_positions_test', 9 );
     1410function adminsanity_menu_top_positions_test( $top ) {
     1411
     1412    // 1.0.3: merge in top level items for WordPress.Com
     1413    return array_merge( $top, array( 'https://wordpress.com/sites', site_url() ) );
     1414}
     1415
    13171416// ---------------------------
    13181417// Test Keep Menu Order Filter
     
    13211420add_filter( 'adminsanity_menu_keep_positions', 'adminsanity_menu_keep_position_test', 9 );
    13221421function adminsanity_menu_keep_position_test( $keep ) {
     1422   
    13231423    // note: prototasq slug is used as an example here to maintain first position (for project management)
    13241424    return array_merge( $keep, array( 'prototasq' ) );
     1425
    13251426}
    13261427
  • adminsanity/trunk/adminsanity/adminsanity-notices.php

    r2821022 r3115930  
    4444// 0.9.9: attempt to prevent double load conflicts
    4545// 1.0.1: use return instead of function wrapper
    46 if ( !function_exists( 'adminsanity_notices_message_levels' ) ) {
    47 
     46if ( !function_exists( 'adminsanity_notices_loader' ) ) {
     47
     48// ---------------------
     49// Notices Loader Action
     50// ---------------------
     51// 1.0.3: added loader action to avoid block editor conflicts
     52add_action( 'admin_init', 'adminsanity_notices_loader' );
     53function adminsanity_notices_loader() {
     54
     55    // --- check for block editor page ---
     56    // 1.0.3: moved internally as flag may note have been set before admin_init
     57
     58    // --- enqueue scripts and styles ---
     59    add_action( 'admin_print_styles', 'adminsanity_notices_styles' );
     60    add_action( 'admin_footer', 'adminsanity_notices_scripts' );
     61   
     62}
    4863
    4964// ------------------
     
    7186    // 0.9.9: added notice-error message class
    7287    // 0.9.9: added woocmmerce message type
     88    // 1.0.3: added e-notice class for elementor notices
     89    // 1.0.3: change notice info label from Notice to Info
     90    // 1.0.3: added woocommerce-store-alerts class
     91    // 1.0.3: added amp-admin-notice class to warnings
    7392    $mtypes = array(
    7493        'error'          => array( 'classes' => 'notice-error error', 'label' => __( 'Errors', 'adminsanity' ) ),
    7594        'update-nag'     => array( 'classes' => 'update-nag', 'label' => __( 'Updates', 'adminsanity' ) ),
    76         'notice-warning' => array( 'classes' => 'notice-warning', 'label' => __( 'Warnings', 'adminsanity' ) ),
     95        'notice-warning' => array( 'classes' => 'notice-warning amp-admin-notice', 'label' => __( 'Warnings', 'adminsanity' ) ),
    7796        'updated'        => array( 'classes' => 'notice-success updated', 'label' => __( 'Messages', 'adminsanity' ) ),
    78         'notice-info'    => array( 'classes' => 'notice-info', 'label' => __( 'Notices', 'adminsanity' ) ),
    79         'commerce'       => array( 'classes' => 'woocommerce-message', 'label' => __( 'Commerce', 'adminsanity') ),
     97        'notice-info'    => array( 'classes' => 'notice-info e-notice', 'label' => __( 'Info', 'adminsanity' ) ),
     98        'commerce'       => array( 'classes' => 'woocommerce-message woocommerce-store-alerts', 'label' => __( 'Commerce', 'adminsanity') ),
    8099    );
    81100    $mtypes = apply_filters( 'adminsanity_notices_message_types', $mtypes );
     
    138157    // --- notices menu ---
    139158    // 0.9.9: add initial collapsed class
    140     echo '<div id="adminsanity-notices-menu" class="postbox collapsed">';
     159    // 1.0.3: change possibly conflicting postbox class
     160    echo '<div id="adminsanity-notices-menu" class="adminsanity-postbox collapsed">';
    141161
    142162    // --- notices menu title ---
    143163    echo '<h3 class="adminsanity-notices-title" onclick="adminsanity_notices_toggle();">';
     164        echo '<div id="adminsanity-notices-arrow">&#9662;</div>';
    144165        echo '<div id="adminsanity-notices-label">' . esc_html( __( 'Notices', 'adminsanity' ) ) . ' &nbsp;</div>';
    145166        echo '<div id="adminsanity-notices-count" class="adminsanity-notices-count"></div>';
    146         echo '<div id="adminsanity-notices-arrow">&#9662;</div>';
    147167    echo '</h3>';
    148168
     
    201221// Notices Styles
    202222// --------------
    203 add_action( 'admin_print_styles', 'adminsanity_notices_styles' );
    204223function adminsanity_notices_styles() {
     224
     225    // --- check for block editor page ---
     226    // 1.0.3: moved internally as flag may note have been set by admin_init
     227    if ( function_exists( 'get_current_screen' ) ) {
     228        $current_screen = get_current_screen();
     229        if ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
     230            return;
     231        }
     232    } elseif ( function_exists( 'is_gutenberg_page' ) && is_gutenberg_page() ) {
     233        return;
     234    }
    205235
    206236    // TODO: get count bubble styles for colour scheme ?
     
    212242    // 0.9.9: added commerce message type tab styles
    213243    // 0.9.9: style/float notices box like screen options/help
     244    // 1.0.3: move left and re-centered vertical arrow position
    214245    $css = "#adminsanity-notices-menu {float: left; margin-bottom: 0; min-width: auto; border-radius: 0 0 4px 4px;}
     246    .adminsanity-postbox {position: relative; min-width: 255px; border: 1px solid #c3c4c7; box-shadow: 0 1px 1px rgba(0, 0, 0, .04); background: #fff;}
    215247    #wpbody h3.adminsanity-notices-title {
    216         cursor:pointer; margin: 0; padding: 2px 14px; display: inline-block; vertical-align:top;
    217         color: #72777c; font-size: 14px; font-weight: normal;}
     248        display: inline-block; vertical-align: top; margin: 0; padding: 2px 10px; margin-top: -3px;
     249        color: #72777c; font-size: 14px; font-weight: normal; cursor: pointer;}
    218250    #wpbody h3.adminsanity-notices-title:hover {color: #32373c;}
    219251    #adminsanity-notices-label, #adminsanity-notices-count, #adminsanity-notices-arrow {display: inline-block; vertical-align: middle;}
    220     #adminsanity-notices-arrow {font-size: 24px; line-height: 28px; color: #72777c; margin-top: -3px;}
    221     #adminsanity-notices-menu.expanded #adminsanity-notices-arrow {margin-bottom: 3px;}
    222     .adminsanity-notices-menu {display: none; margin: 2px 7px 0px 7px; padding: 0 1px 4px 1px; min-width: 65px;
     252    #adminsanity-notices-arrow {font-size: 24px; line-height: 28px; color: #72777c; margin-right: 5px;}
     253    .adminsanity-notices-menu {display: none; margin: 2px 7px 0px 7px; padding: 0 1px 4px 1px; min-width: 75px;
    223254        text-align: center; font-size: 12px; line-height: 16px; border-left: 1px solid transparent; border-right: 1px solid transparent;}
    224     .adminsanity-notices-menu.level {min-width: 45px; margin-top: 0px; padding-top: 4px;}
     255    .adminsanity-notices-menu.level {margin-top: 0px; min-width: 55px;}
    225256    .adminsanity-notices-menu.active {background-color: #F7F7F7; border-left: 1px solid #ccc; border-right: 1px solid #ccc;}
    226     .adminsanity-notices-menu.level.active {border-top: 1px solid #ccc;}
     257    .adminsanity-notices-menu.level.active {border-top: 3px solid #ccc;}
    227258    .adminsanity-notices-menu:hover {background-color: #FAFAFA;}
    228259    .adminsanity-notices-menu a {cursor: pointer; vertical-align: middle;}
     
    254285// Notices Scripts
    255286// ---------------
    256 add_action( 'admin_footer', 'adminsanity_notices_scripts' );
    257287function adminsanity_notices_scripts() {
     288
     289    // --- check for block editor or gutenberg plugin page ---
     290    // 1.0.3: moved internally as flag may note have been set before admin_init
     291    if ( function_exists( 'get_current_screen' ) ) {
     292        $current_screen = get_current_screen();
     293        if ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
     294            return;
     295        }
     296    } elseif ( function_exists( 'is_gutenberg_page' ) && is_gutenberg_page() ) {
     297        return;
     298    }
    258299
    259300    $js = '';
     
    322363    // 0.9.8: fix for extra notice-success class
    323364    // 0.9.9: fix to handle multiple classes dynamically
     365    // 1.0.3: do not float right on collapse click
     366    // 1.0.3: style fix to centralize up/down arrow
    324367    $js .= "for (i = 0; i < as_notice_levels.length; i++) {
    325368        if (as_notice_levels[i] != 'all') {
     
    353396        if (jQuery('#adminsanity-notices-menu').hasClass('expanded')) {
    354397            jQuery('#adminsanity-notices-menu').removeClass('expanded').addClass('collapsed');
    355             jQuery('#adminsanity-notices-menu').css('float','right');
     398            /* jQuery('#adminsanity-notices-menu').css('float','right'); */
    356399            jQuery('#adminsanity-notices-count').show();
    357400            jQuery('#adminsanity-notices-wrap').animate({'height':'0px'},750);
    358401            as_notices_height = 0;
    359402            jQuery('#adminsanity-notices-arrow').html('&#9662;');
    360             jQuery('.adminsanity-notices-menu, .adminsanity-notices-menu-spacer').hide();
     403            /* jQuery('.adminsanity-notices-menu, .adminsanity-notices-menu-spacer').hide(); */
     404            jQuery('.adminsanity-notices-menu.level').hide();
    361405        } else {
    362406            jQuery('#adminsanity-notices-menu').removeClass('collapsed').addClass('expanded');
    363             jQuery('#adminsanity-notices-menu').css('float','left');
     407            /* jQuery('#adminsanity-notices-menu').css('float','left'); */
    364408            jQuery('#adminsanity-notices-count').hide();
    365409            adminsanity_notices_height(1500);
    366410            jQuery('#adminsanity-notices-arrow').html('&#9652;');
    367             jQuery('.adminsanity-notices-menu, .adminsanity-notices-menu-spacer').css('display','inline-block');
     411            /* jQuery('.adminsanity-notices-menu, .adminsanity-notices-menu-spacer').css('display','inline-block'); */
     412            jQuery('.adminsanity-notices-menu.level').css('display','inline-block');
    368413        }
    369414    }
  • adminsanity/trunk/loader.php

    r2821022 r3115930  
    44// === Plugin Panel Loader Class ===
    55// =================================
    6 //
     6
     7if ( !defined( 'ABSPATH' ) ) exit;
     8
    79// --------------
    8 // Version: 1.2.8
     10// Version: 1.3.0
    911// --------------
    1012// Note: Changelog and structure at end of file.
     
    228230            if ( !isset( $args['proslug'] ) ) {
    229231                $proslug = $this->plugin_data( '@fs_premium_only' );
    230                 // 1.0.1: if more than one file, extract pro slug based on the first filename
    231                 if ( !strstr( $proslug, ',' ) ) {
    232                     $profiles = array( $proslug );
    233                     $proslug = trim( $proslug );
    234                 } else {
    235                     $profiles = explode( ',', $proslug );
    236                     $proslug = trim( $profiles[0] );
    237                 }
    238                 $args['proslug'] = substr( $proslug, 0, - 4 ); // strips .php extension
    239                 $args['profiles'] = $profiles;
     232                // 1.3.0: check for pro slug string
     233                if ( is_string( $proslug ) ) {
     234                    // 1.0.1: if more than one file, extract pro slug based on the first filename
     235                    if ( !strstr( $proslug, ',' ) ) {
     236                        $profiles = array( $proslug );
     237                        $proslug = trim( $proslug );
     238                    } else {
     239                        $profiles = explode( ',', $proslug );
     240                        $proslug = trim( $profiles[0] );
     241                    }
     242                    $args['proslug'] = substr( $proslug, 0, - 4 ); // strips .php extension
     243                    $args['profiles'] = $profiles;
     244                }
    240245            }
    241246
     
    434439            // 1.0.5: use sanitize_title on request variables
    435440            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    436             if ( sanitize_title( $_REQUEST['page'] ) != $args['slug'] ) {
     441            if ( sanitize_text_field( $_REQUEST['page'] ) != $args['slug'] ) {
    437442                return;
    438443            }
     
    441446            }
    442447            // phpcs:ignore WordPress.Security.NonceVerification.Missing
    443             if ( 'reset' != sanitize_title( $_POST[$args['namespace'] . '_update_settings'] ) ) {
     448            if ( 'reset' != sanitize_text_field( $_POST[$args['namespace'] . '_update_settings'] ) ) {
    444449                return;
    445450            }
     
    452457
    453458            // --- verify nonce ---
    454             // $noncecheck = wp_verify_nonce( $_POST['_wpnonce', $args['slug'].'_update_settings' );
     459            // $noncecheck = wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), $args['slug'] . '_update_settings' );
    455460            check_admin_referer( $args['slug'] . '_update_settings' );
    456461
     
    482487            // 1.0.3: only use namespace not settings key
    483488            // 1.0.9: check page is set and matches slug
    484             if ( !isset( $_REQUEST['page'] ) || ( $_REQUEST['page'] != $args['slug'] ) ) {
     489            if ( !isset( $_REQUEST['page'] ) || ( sanitize_text_field( $_REQUEST['page'] != $args['slug'] ) ) ) {
    485490                return;
    486491            }
    487492            $updatekey = $args['namespace'] . '_update_settings';
    488             if ( !isset( $_POST[$updatekey] ) || ( 'yes' != $_POST[$args['namespace'] . '_update_settings'] ) ) {
     493            // phpcs:ignore WordPress.Security.NonceVerification.Missing
     494            if ( !isset( $_POST[$updatekey] ) || ( 'yes' != sanitize_text_field( $_POST[$args['namespace'] . '_update_settings'] ) ) ) {
    489495                return;
    490496            }
     
    497503
    498504            // --- verify nonce ---
    499             // $noncecheck = wp_verify_nonce( $_POST['_wpnonce', $args['slug'].'_update_settings' );
     505            // $noncecheck = wp_verify_nonce( sanitize_text_field( $_POST['_wpnonce'] ), $args['slug'] . '_update_settings' );
    500506            check_admin_referer( $args['slug'] . '_update_settings' );
    501507
     
    619625                        // --- text area ---
    620626                        // 1.2.5: use sanitize_textarea_field with stripslashes
    621                         $posted = isset( $_POST[$postkey] ) ? sanitize_textarea_field( stripslashes( $_POST[$postkey] ) ) : null;
     627                        $posted = isset( $_POST[$postkey] ) ? sanitize_textarea_field( $_POST[$postkey] ) : null;
     628                        // 1.3.0: move use of stripslashes to separate line
     629                        if ( !is_null( $posted ) ) {
     630                            $posted = stripslashes( $posted );
     631                        }
    622632                        $settings[$key] = $posted;
    623633
     
    629639                        if ( !is_string( $valid ) ) {
    630640                            $valid = 'TEXT';
     641                        }
     642                        $newsettings = $posted;
     643
     644                    } elseif ( 'email' == $type ) {
     645
     646                        // --- email field ---
     647                        // 1.3.0: added explicitly for email field type
     648                        $posted = isset( $_POST[$postkey] ) ? sanitize_text_field( $_POST[$postkey] ) : null;
     649                        if ( !is_string( $valid ) ) {
     650                            $valid = 'EMAIL';
    631651                        }
    632652                        $newsettings = $posted;
     
    783803                        $settings[$key] = $posted;
    784804
     805                    } else {
     806                       
     807                        // --- fallback to text type ---
     808                        // 1.3.0: added for unspecified option field type
     809                        $posted = isset( $_POST[$postkey] ) ? sanitize_text_field( $_POST[$postkey] ) : null;
     810                        if ( !is_string( $valid ) ) {
     811                            $valid = 'TEXT';
     812                        }
     813                        $newsettings = $posted;                     
     814                       
    785815                    }
    786816
     
    795825                            if ( isset( $settings[$key] ) ) {
    796826                                // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    797                                 echo '(Validated) ' . esc_html( print_r( $settings[$key], true ) ) . '<br>' . PHP_EOL;
     827                                echo '(Validated) ' . esc_html( print_r( $settings[$key], true ) ) . '<br>' . "\n";
    798828                            } else {
    799829                                echo 'No setting yet for key ' . esc_html( $key ) . '<br>' . "\n";
     
    913943                    if ( count( $tabs ) > 0 ) {
    914944                        // 1.2.5: sanitize current tab value before validating
    915                         $currenttab = sanitize_title( $_POST['settingstab'] );
     945                        $currenttab = sanitize_text_field( $_POST['settingstab'] );
    916946                        if ( in_array( $currenttab, $tabs ) ) {
    917947                            $settings['settingstab'] = $currenttab;
     
    13531383
    13541384                // --- output plugin info ---
    1355                 echo '<b>' . esc_html( __( 'Plugin Name' ) ) . '</b>: ' . esc_html( $parsed['name'] ) . '<br>' . PHP_EOL;
    1356                 // echo '<b>' . esc_html( __( 'Tags' ) ) . '</b>: ' . esc_html( implode( ', ', $parsed['tags'] ) ) . '<br>' . PHP_EOL;
    1357                 echo '<b>' . esc_html( __( 'Requires at least' ) ) . '</b>: ' . esc_html( __( 'WordPress' ) ) . ' v' . esc_html( $parsed['requires_at_least'] ) . '<br>' . PHP_EOL;
    1358                 echo '<b>' . esc_html( __( 'Tested up to' ) ) . '</b>: ' . esc_html( __( 'WordPress' ) ) . ' v' . esc_html( $parsed['tested_up_to'] ) . '<br>' . PHP_EOL;
     1385                echo '<b>' . esc_html( __( 'Plugin Name' ) ) . '</b>: ' . esc_html( $parsed['name'] ) . '<br>' . "\n";
     1386                // echo '<b>' . esc_html( __( 'Tags' ) ) . '</b>: ' . esc_html( implode( ', ', $parsed['tags'] ) ) . '<br>' . "\n";
     1387                echo '<b>' . esc_html( __( 'Requires at least' ) ) . '</b>: ' . esc_html( __( 'WordPress' ) ) . ' v' . esc_html( $parsed['requires_at_least'] ) . '<br>' . "\n";
     1388                echo '<b>' . esc_html( __( 'Tested up to' ) ) . '</b>: ' . esc_html( __( 'WordPress' ) ) . ' v' . esc_html( $parsed['tested_up_to'] ) . '<br>' . "\n";
    13591389                if ( isset( $parsed['stable_tag'] ) ) {
    1360                     echo '<b>' . esc_html( __( 'Stable Tag' ) ) . '</b>: ' . esc_html( $parsed['stable_tag'] ) . '<br>' . PHP_EOL;
    1361                 }
    1362                 echo '<b>' . esc_html( __( 'Contributors' ) ) . '</b>: ' . esc_html( implode( ', ', $parsed['contributors'] ) ) . '<br>' . PHP_EOL;
     1390                    echo '<b>' . esc_html( __( 'Stable Tag' ) ) . '</b>: ' . esc_html( $parsed['stable_tag'] ) . '<br>' . "\n";
     1391                }
     1392                echo '<b>' . esc_html( __( 'Contributors' ) ) . '</b>: ' . esc_html( implode( ', ', $parsed['contributors'] ) ) . '<br>' . "\n";
    13631393                // echo '<b>Donate Link</b>: <a href="' . esc_url( $parsed['donate_link'] ) . '" target="_blank">' . esc_html( $parsed['donate_link'] ) . '</a><br>';
    13641394                // 1.2.5: use wp_kses_post on plugin short description markup
    1365                 echo '<br>' . wp_kses_post( $parsed['short_description'] ) . '<br><br>' . PHP_EOL;
     1395                echo '<br>' . wp_kses_post( $parsed['short_description'] ) . '<br><br>' . "\n";
    13661396
    13671397                // --- output sections ---
     
    13801410                        }
    13811411                        $title = implode( ' ', $parts );
    1382                         echo '<h3>' . esc_html( $title ) . '</h3>' . PHP_EOL;
     1412                        echo '<h3>' . esc_html( $title ) . '</h3>' . "\n";
    13831413                        // 1.2.5: use wp_kses_post on readme section output
    13841414                        echo wp_kses_post( $section );
     
    13861416                }
    13871417                if ( isset( $parsed['remaining_content'] ) && !empty( $remaining_content ) ) {
    1388                     echo '<h3>' . esc_html( __( 'Extra Notes' ) ) . '</h3>' . PHP_EOL;
     1418                    echo '<h3>' . esc_html( __( 'Extra Notes' ) ) . '</h3>' . "\n";
    13891419                    // 1.2.5: use wp_kses_post on readme extra notes output
    13901420                    echo wp_kses_post( $parsed['remaining_content'] );
     
    15151545                    $args['contact'] = $premium;
    15161546                }
     1547                if ( !isset( $args['affiliation'] ) ) {
     1548                    $args['affiliaation'] = false;
     1549                }
    15171550
    15181551                // --- set Freemius settings from plugin settings ---
     1552                // ref: https://freemius.com/help/documentation/wordpress-sdk/integrating-freemius-sdk/
    15191553                // 1.1.1: remove admin_url wrapper on Freemius first-path value
     1554                // 1.3.0: added has_affiliation argument key
    15201555                // TODO: further possible args for Freemius init (eg. bundle_id)
    1521                 // ref: https://freemius.com/help/documentation/wordpress-sdk/integrating-freemius-sdk/
    15221556                $first_path = add_query_arg( 'page', $args['slug'], 'admin.php' );
    15231557                $first_path = add_query_arg( 'welcome', 'true', $first_path );
     
    15311565                    'is_org_compliant' => $args['wporg'],
    15321566                    'is_premium'       => $premium,
     1567                    'has_affiliation'  => $args['affiliation'],
    15331568                    'menu'             => array(
    15341569                        'slug'       => $args['slug'],
     
    15491584                if ( $this->debug ) {
    15501585                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    1551                     echo '<span style="display:none;">Freemius Settings: ' . esc_html( print_r( $settings, true ) ) . '</span>' . PHP_EOL;
     1586                    echo '<span style="display:none;">Freemius Settings: ' . esc_html( print_r( $settings, true ) ) . '</span>' . "\n";
    15521587                }
    15531588                if ( !$settings || !is_array( $settings ) ) {
     
    15571592                // --- initialize Freemius now ---
    15581593                $freemius = $GLOBALS[$namespace . '_freemius'] = fs_dynamic_init( $settings );
    1559                 if ( $this->debug ) {
    1560                     // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    1561                     echo '<span style="display:none;">Freemius Object: ' . esc_html( print_r( $freemius, true ) ) . '</span>' . PHP_EOL;
    1562                 }
    15631594
    15641595                // --- set plugin basename ---
     
    15711602                $this->freemius_connect();
    15721603
     1604                // --- Freemius Object Debug ---
     1605                if ( $this->debug && current_user_can( 'manage_options' ) ) {
     1606                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions
     1607                    echo '<span style="display:none;">Freemius Object: ' . esc_html( print_r( $freemius, true ) ) . '</span>' . "\n";
     1608                }
     1609               
    15731610                // --- fire Freemius loaded action ---
    15741611                do_action( $args['namespace'] . '_loaded' );
     
    16581695                // 1.0.8: check settingsmenu switch that disables automatic settings menu adding
    16591696                if ( !isset( $args['settingsmenu'] ) || ( false !== $args['settingsmenu'] ) ) {
    1660                     add_options_page( $args['pagetitle'], $args['menutitle'], $args['capability'], $args['slug'], $args['namespace'] . '_settings_page' );
     1697                    // 1.3.0: use filtered pagetitle and menutitle
     1698                    add_options_page( $pagetitle, $menutitle, $args['capability'], $args['slug'], $args['namespace'] . '_settings_page' );
    16611699                }
    16621700            }
     
    17281766                if ( $this->debug ) {
    17291767                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    1730                     echo '<span style="display:none;">Plugin Links for ' . esc_html( $file ) . ': ' . esc_html( print_r( $links, true ) ) . '</span>' . PHP_EOL;
     1768                    echo '<span style="display:none;">Plugin Links for ' . esc_html( $file ) . ': ' . esc_html( print_r( $links, true ) ) . '</span>' . "\n";
    17311769                }
    17321770            }
     
    17451783            }
    17461784
    1747             echo '<table style="background-color: lightYellow; border-style:solid; border-width:1px; border-color: #E6DB55; text-align:center;">' . PHP_EOL;
    1748                 echo '<tr><td>' . PHP_EOL;
    1749                     echo '<div class="message" style="margin:0.25em; font-weight:bold;">' . PHP_EOL;
     1785            echo '<table style="background-color: lightYellow; border-style:solid; border-width:1px; border-color: #E6DB55; text-align:center;">' . "\n";
     1786                echo '<tr><td>' . "\n";
     1787                    echo '<div class="message" style="margin:0.25em; font-weight:bold;">' . "\n";
    17501788                        // 1.2.5: added wp_kses_post to message output
    1751                         echo wp_kses_post( $message ) . PHP_EOL;
    1752                     echo '</div>' . PHP_EOL;
    1753                 echo '</td></tr>' . PHP_EOL;
    1754             echo '</table>' . PHP_EOL;
     1789                        echo wp_kses_post( $message ) . "\n";
     1790                    echo '</div>' . "\n";
     1791                echo '</td></tr>' . "\n";
     1792            echo '</table>' . "\n";
    17551793            if ( !$echo ) {
    17561794                $box = ob_get_contents();
     
    17751813            // 1.0.5: use sanitize_title on request variable
    17761814            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    1777             if ( substr( sanitize_title( $_REQUEST['page'] ), 0, strlen( $args['slug'] ) ) != $args['slug'] ) {
     1815            if ( substr( sanitize_text_field( $_REQUEST['page'] ), 0, strlen( $args['slug'] ) ) != $args['slug'] ) {
    17781816                return;
    17791817            }
     
    17851823
    17861824            // --- output notice box ---
    1787             echo '<div style="width: 98%;" id="admin-notices-box" class="postbox">' . PHP_EOL;
    1788             echo '<h3 class="admin-notices-title" style="cursor:pointer; margin:7px 14px; font-size:16px;" onclick="settings_toggle_notices();">' . PHP_EOL;
    1789             echo '<span id="admin-notices-arrow" style="font-size:24px;">&#9656;</span> &nbsp; ' . PHP_EOL;
    1790             echo '<span id="admin-notices-title" style="vertical-align:top;">' . esc_html( __( 'Notices' ) ) . '</span>  &nbsp; ' . PHP_EOL;
    1791             echo '<span id="admin-notices-count" style="vertical-align:top;"></span></h3>' . PHP_EOL;
    1792 
    1793             echo '<div id="admin-notices-wrap" style="display:none";><h2 style="display:none;"></h2></div>' . PHP_EOL;
    1794             echo '</div>' . PHP_EOL;
     1825            echo '<div style="width: 98%;" id="admin-notices-box" class="postbox">' . "\n";
     1826            echo '<h3 class="admin-notices-title" style="cursor:pointer; margin:7px 14px; font-size:16px;" onclick="settings_toggle_notices();">' . "\n";
     1827            echo '<span id="admin-notices-arrow" style="font-size:24px;">&#9656;</span> &nbsp; ' . "\n";
     1828            echo '<span id="admin-notices-title" style="vertical-align:top;">' . esc_html( __( 'Notices' ) ) . '</span>  &nbsp; ' . "\n";
     1829            echo '<span id="admin-notices-count" style="vertical-align:top;"></span></h3>' . "\n";
     1830
     1831            echo '<div id="admin-notices-wrap" style="display:none";><h2 style="display:none;"></h2></div>' . "\n";
     1832            echo '</div>' . "\n";
    17951833
    17961834            // --- toggle notice box script ---
     
    18311869                // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    18321870                echo esc_html( print_r( $settings, true ) );
    1833                 echo '<br><br>' . PHP_EOL;
     1871                echo '<br><br>' . "\n";
    18341872
    18351873                echo '<br><b>Plugin Options:</b><br>';
    18361874                // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    18371875                echo esc_html( print_r( $this->options, true ) );
    1838                 echo '<br><br>' . PHP_EOL;
     1876                echo '<br><br>' . "\n";
    18391877
    18401878                // phpcs:ignore WordPress.Security.NonceVerification.Missing
     
    18421880                    echo '<br><b>Posted Values:</b><br>';
    18431881                    // phpcs:ignore WordPress.Security.NonceVerification.Missing
    1844                     foreach ( $_POST as $key => $value ) {
     1882                    $posted = array_map( 'sanitize_text_field', $_POST );
     1883                    foreach ( $posted as $key => $value ) {
    18451884                        // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    1846                         echo esc_attr( $key ) . ': ' . esc_html( print_r( $value, true ) ) . '<br>' . PHP_EOL;
     1885                        echo esc_html( $key ) . ': ' . esc_html( print_r( $value, true ) ) . '<br>' . "\n";
    18471886                    }
    18481887                }
     
    18711910
    18721911            // --- open header table ---
    1873             echo '<table class="plugin-settings-page-header"><tr>' . PHP_EOL;
     1912            echo '<table class="plugin-settings-page-header"><tr>' . "\n";
    18741913
    18751914            // --- plugin icon ---
    18761915            // 1.1.9: add filter for plugin icon url
    18771916            $icon_url = apply_filters( $namespace . '_settings_page_icon_url', $icon_url );
    1878             echo '<td>' . PHP_EOL;
     1917            echo '<td>' . "\n";
    18791918            if ( $icon_url ) {
    1880                 echo '<img class="plugin-settings-page-icon" src="' . esc_url( $icon_url ) . '" width="128" height="128">' . PHP_EOL;
    1881             }
    1882             echo '</td>' . PHP_EOL;
    1883 
    1884             echo '<td width="20"></td><td>' . PHP_EOL;
    1885 
    1886             echo '<table><tr>' . PHP_EOL;
     1919                echo '<img class="plugin-settings-page-icon" src="' . esc_url( $icon_url ) . '" width="128" height="128">' . "\n";
     1920            }
     1921            echo '</td>' . "\n";
     1922
     1923            echo '<td width="20"></td><td>' . "\n";
     1924
     1925            echo '<table><tr>' . "\n";
    18871926
    18881927            // --- plugin title ---
    18891928            // 1.1.9: add filter for plugin pagetitle
    1890             $title = apply_filters( $namespace . '_settings_page_title', $args['title'] ) . PHP_EOL;
    1891             echo '<td><h3 style="font-size:20px;">' . PHP_EOL;
    1892             echo '<a href="' . esc_url( $args['home'] ) . '" target="_blank" style="text-decoration:none;">' . esc_html( $title ) . '</a>' . PHP_EOL;
    1893             echo '</h3></td>' . PHP_EOL;
    1894 
    1895             echo '<td width="20"></td>' . PHP_EOL;
     1929            $title = apply_filters( $namespace . '_settings_page_title', $args['title'] );
     1930            echo '<td><h3 style="font-size:20px;">' . "\n";
     1931            echo '<a href="' . esc_url( $args['home'] ) . '" target="_blank" style="text-decoration:none;">' . esc_html( $title ) . '</a>' . "\n";
     1932            echo '</h3></td>' . "\n";
     1933
     1934            echo '<td width="20"></td>' . "\n";
    18961935
    18971936            // --- plugin version ---
    18981937            // 1.1.9: add filter for plugin version
    18991938            $version = apply_filters( $namespace . '_settings_page_version', 'v' . $args['version'] );
    1900             echo '<td><h3 class="plugin-setttings-page-version">' . esc_html( $version ) . '</h3></td></tr>' . PHP_EOL;
     1939            echo '<td><h3 class="plugin-setttings-page-version">' . esc_html( $version ) . '</h3></td></tr>' . "\n";
    19011940
    19021941            // --- subtitle ---
     
    19041943            $subtitle = apply_filters( $namespace . '_settings_page_subtitle', '' );
    19051944            if ( '' != $subtitle ) {
    1906                 echo '<tr><td colspan="3" align="center">' . PHP_EOL;
    1907                 echo '<h4 class="plugins-settings-page-subtitle" style="font-size:14px; margin-top:0;">' . esc_html( $subtitle ) . '</h4>' . PHP_EOL;
    1908                 echo '</td></tr>' . PHP_EOL;
    1909             }
    1910 
    1911             echo '<tr><td colspan="3" align="center">' . PHP_EOL;
    1912 
    1913             echo '<table><tr><td align="center">' . PHP_EOL;
     1945                echo '<tr><td colspan="3" align="center">' . "\n";
     1946                echo '<h4 class="plugins-settings-page-subtitle" style="font-size:14px; margin-top:0;">' . esc_html( $subtitle ) . '</h4>' . "\n";
     1947                echo '</td></tr>' . "\n";
     1948            }
     1949
     1950            echo '<tr><td colspan="3" align="center">' . "\n";
     1951
     1952            echo '<table><tr><td align="center">' . "\n";
    19141953
    19151954            // ---- plugin author ---
     
    19171956            if ( isset( $args['author_url'] ) ) {
    19181957                echo '<font style="font-size:16px;">' . esc_html( __( 'by' ) ) . '</font> ';
    1919                 echo '<a href="' . esc_url( $args['author_url'] ) . '" target="_blank" style="text-decoration:none;font-size:16px;" target="_blank"><b>' . esc_html( $args['author'] ) . '</b></a><br><br>' . PHP_EOL;
     1958                echo '<a href="' . esc_url( $args['author_url'] ) . '" target="_blank" style="text-decoration:none;font-size:16px;" target="_blank"><b>' . esc_html( $args['author'] ) . '</b></a><br><br>' . "\n";
    19201959            }
    19211960
     
    19511990            // --- author icon ---
    19521991            if ( $author_icon_url ) {
    1953                 echo '</td><td>' . PHP_EOL;
     1992                echo '</td><td>' . "\n";
    19541993
    19551994                // 1.0.8: check if author URL is set for link
    19561995                if ( isset( $args['author_url'] ) ) {
    1957                     echo '<a href="' . esc_url( $args['author_url'] ) . '" target="_blank">' . PHP_EOL;
    1958                 }
    1959                 echo '<img src="' . esc_url( $author_icon_url ) . '" width="64" height="64" border="0">' . PHP_EOL;
     1996                    echo '<a href="' . esc_url( $args['author_url'] ) . '" target="_blank">' . "\n";
     1997                }
     1998                echo '<img src="' . esc_url( $author_icon_url ) . '" width="64" height="64" border="0">' . "\n";
    19601999                if ( isset( $args['author_url'] ) ) {
    1961                     echo '</a>' . PHP_EOL;
    1962                 }
    1963             }
    1964 
    1965             echo '</td></tr></table>' . PHP_EOL;
    1966 
    1967             echo '</td></tr></table>' . PHP_EOL;
    1968 
    1969             echo '</td><td width="50"></td><td style="vertical-align:top;">' . PHP_EOL;
     2000                    echo '</a>' . "\n";
     2001                }
     2002            }
     2003
     2004            echo '</td></tr></table>' . "\n";
     2005
     2006            echo '</td></tr></table>' . "\n";
     2007
     2008            echo '</td><td width="50"></td><td style="vertical-align:top;">' . "\n";
    19702009
    19712010            // --- plugin supporter links ---
    19722011            // 1.0.1: set rate/share/donate links and texts
    19732012            // 1.0.8: added filters for rate/share/donate links
    1974             echo '<br><div class="plugin-settings-page-links">' . PHP_EOL;
     2013            echo '<br><div class="plugin-settings-page-links">' . "\n";
    19752014
    19762015            // --- Rate link ---
     
    19902029                }
    19912030                $rate_link = '<a href="' . esc_url( $rate_url ) . '" class="pluginlink" target="_blank">';
    1992                 $rate_link .= '<span style="font-size:24px; color:#FC5; margin-right:10px;" class="dashicons dashicons-star-filled"></span>' . PHP_EOL;
    1993                 $rate_link .= ' ' . esc_html( $rate_text ) . '</a><br><br>' . PHP_EOL;
     2031                $rate_link .= '<span style="font-size:24px; color:#FC5; margin-right:10px;" class="dashicons dashicons-star-filled"></span>' . "\n";
     2032                $rate_link .= ' ' . esc_html( $rate_text ) . '</a><br><br>' . "\n";
    19942033                $rate_link = apply_filters( $args['namespace'] . '_rate_link', $rate_link, $args );
    19952034                if ( $rate_link ) {
     
    20332072            }
    20342073
    2035             echo '</div></td></tr>' . PHP_EOL;
     2074            echo '</div></td></tr>' . "\n";
    20362075
    20372076            // --- output updated and reset messages ---
     
    20392078            if ( isset( $_GET['updated'] ) ) {
    20402079                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    2041                 $updated = sanitize_title( $_GET['updated'] );
     2080                $updated = sanitize_text_field( $_GET['updated'] );
    20422081                if ( 'yes' == $updated ) {
    20432082                    $message = $settings['title'] . ' ' . __( 'Settings Updated.' );
     
    20482087                }
    20492088                if ( isset( $message ) ) {
    2050                     echo '<tr><td></td><td></td><td align="center">' . PHP_EOL;
     2089                    echo '<tr><td></td><td></td><td align="center">' . "\n";
    20512090                    // 1.2.5: use direct echo option for message box
    20522091                    $this->message_box( $message, true );
    2053                     echo '</td></tr>' . PHP_EOL;
     2092                    echo '</td></tr>' . "\n";
    20542093                }
    20552094            } else {
     
    20572096                // 1.0.5: use sanitize_title on request variable
    20582097                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    2059                 if ( isset( $_REQUEST['welcome'] ) && ( 'true' == sanitize_title( $_REQUEST['welcome'] ) ) ) {
     2098                if ( isset( $_REQUEST['welcome'] ) && ( 'true' == sanitize_text_field( $_REQUEST['welcome'] ) ) ) {
    20602099                    // 1.2.3: skip output if welcome message argument is empty
    20612100                    if ( isset( $args['welcome'] ) && ( '' != $args['welcome'] ) ) {
     
    20632102                        // 1.2.5: use direct echo option for message box
    20642103                        $this->message_box( $args['welcome'], true );
    2065                         echo '</td></tr>' . PHP_EOL;
     2104                        echo '</td></tr>' . "\n";
    20662105                    }
    20672106                }
    20682107            }
    20692108
    2070             echo '</table><br>' . PHP_EOL;
     2109            echo '</table><br>' . "\n";
    20712110        }
    20722111
     
    20792118
    20802119            // --- open page wrapper ---
    2081             echo '<div id="pagewrap" class="wrap" style="width:100%;margin-right:0px !important;">' . PHP_EOL;
     2120            echo '<div id="pagewrap" class="wrap" style="width:100%;margin-right:0 !important;">' . "\n";
    20822121
    20832122            do_action( $namespace . '_admin_page_top' );
     
    20942133
    20952134            // --- close page wrapper ---
    2096             echo '</div>' . PHP_EOL;
     2135            echo '</div>' . "\n";
    20972136        }
    20982137
     
    21502189            // --- output saved settings ---
    21512190            if ( $this->debug ) {
    2152                 echo '<br><b>Saved Settings:</b><br>';
     2191                echo '<br><b>Saved Settings:</b><br>' . "\n";
    21532192                // phpcs:ignore WordPress.PHP.DevelopmentFunctions
    21542193                echo esc_html( print_r( $settings, true ) );
    2155                 echo '<br><br>';
     2194                echo '<br><br>' . "\n";
    21562195            }
    21572196
     
    22092248
    22102249                $i = 0;
    2211                 echo '<ul id="settings-tab-buttons">' . PHP_EOL;
     2250                echo '<ul id="settings-tab-buttons">' . "\n";
    22122251                foreach ( $tabs as $tab => $tablabel ) {
    22132252                    $class = 'inactive';
     
    22172256                    // 1.2.5: remove onclick attribute and use jQuery click function
    22182257                    // onclick="plugin_panel_display_tab(\'' . esc_attr( $tab ) . '\');"
    2219                     echo '<li id="' . esc_attr( $tab ) . '-tab-button" class="settings-tab-button ' . esc_attr( $class ) . '">' . esc_html( $tablabel ) . '</li>' . PHP_EOL;
    2220                     $i ++;
    2221                 }
    2222                 echo '</ul>' . PHP_EOL;
     2258                    echo '<li id="' . esc_attr( $tab ) . '-tab-button" class="settings-tab-button ' . esc_attr( $class ) . '">' . esc_html( $tablabel ) . '</li>' . "\n";
     2259                    $i++;
     2260                }
     2261                echo '</ul>' . "\n";
    22232262            } else {
    22242263                $tabs = array( 'general' => __( 'General' ) );
     
    22312270            // --- start settings form ---
    22322271            // 1.2.0: remove unused prefix on settings tab name attribute
    2233             echo '<form method="post" id="settings-form">' . PHP_EOL;
    2234             echo '<input type="hidden" name="' . esc_attr( $namespace ) . '_update_settings" id="settings-action" value="yes">' . PHP_EOL;
    2235             echo '<input type="hidden" name="settingstab" id="settings-tab" value="' . esc_attr( $currenttab ) . '">' . PHP_EOL;
     2272            echo '<form method="post" id="settings-form">' . "\n";
     2273            echo '<input type="hidden" name="' . esc_attr( $namespace ) . '_update_settings" id="settings-action" value="yes">' . "\n";
     2274            echo '<input type="hidden" name="settingstab" id="settings-tab" value="' . esc_attr( $currenttab ) . '">' . "\n";
    22362275            wp_nonce_field( $args['slug'] . '_update_settings' );
    22372276
    22382277            // --- maybe set hidden debug input ---
    22392278            if ( $this->debug ) {
    2240                 echo '<input type="hidden" name="debug" value="yes">' . PHP_EOL;
     2279                echo '<input type="hidden" name="debug" value="yes">' . "\n";
    22412280            }
    22422281
    22432282            // ---- open wrapbox ---
    2244             echo '<div id="wrapbox" class="postbox" style="line-height:2em;">' . PHP_EOL;
    2245             echo '<div class="inner" style="padding-left:20px;">' . PHP_EOL;
     2283            echo '<div id="wrapbox" class="postbox" style="line-height:2em;">' . "\n";
     2284            echo '<div class="inner" style="padding-left:20px;">' . "\n";
    22462285
    22472286            // --- output tabbed sections ---
     
    22542293                    $class = 'active';
    22552294                }
    2256                 echo '<div id="' . esc_attr( $tab ) . '-tab" class="settings-tab ' . esc_attr( $class ) . '">' . PHP_EOL;
     2295                echo '<div id="' . esc_attr( $tab ) . '-tab" class="settings-tab ' . esc_attr( $class ) . '">' . "\n";
    22572296
    22582297                do_action( $namespace . '_admin_page_tab_' . $tab . '_top' );
    22592298
    2260                 echo '<table cellpadding="0" cellspacing="0">' . PHP_EOL;
     2299                echo '<table cellpadding="0" cellspacing="0">' . "\n";
    22612300
    22622301                if ( count( $sections ) > 0 ) {
     
    22692308                            // --- section top ---
    22702309                            // 1.2.5: fix to mismatched class setting-section-bottom
    2271                             echo '<tr class="setting-section-top"><td colspan="5">' . PHP_EOL;
     2310                            echo '<tr class="setting-section-top"><td colspan="5">' . "\n";
    22722311                            // 1.2.5: use do_action directly instead of using stored output
    22732312                            do_action( $namespace . '_admin_page_section_' . $section . '_top' );
    2274                             echo '</td></tr>' . PHP_EOL;
     2313                            echo '</td></tr>' . "\n";
    22752314
    22762315                            // --- section heading ---
    22772316                            if ( !isset( $sectionheadings[$section] ) ) {
    2278                                 echo '<tr class="setting-section">' . PHP_EOL;
    2279                                 echo '<td colspan="5"><h3>' . esc_html( $sectionlabel ) . '</h3></td>' . PHP_EOL;
    2280                                 echo '</tr>' . PHP_EOL;
     2317                                echo '<tr class="setting-section">' . "\n";
     2318                                echo '<td colspan="5"><h3>' . esc_html( $sectionlabel ) . '</h3></td>' . "\n";
     2319                                echo '</tr>' . "\n";
    22812320                                $sectionheadings[$section] = true;
    22822321                            }
     
    22882327                                echo wp_kses( $this->setting_row( $option ), $this->allowed_html( $option ) );
    22892328                            }
    2290                             echo '<tr height="25"><td> </td></tr>' . PHP_EOL;
     2329                            echo '<tr height="25"><td> </td></tr>' . "\n";
    22912330
    22922331                            // --- section bottom hook ---
     
    22942333                            // 1.2.5: use do_action directly instead of using stored output
    22952334                            do_action( $namespace . '_admin_page_section_' . $section . '_bottom' );
    2296                             echo '</td></tr>' . PHP_EOL;
     2335                            echo '</td></tr>' . "\n";
    22972336
    22982337                        }
     
    23022341                    foreach ( $taboptions[$tab]['general'] as $key => $option ) {
    23032342                        $option['key'] = $key;
    2304                         echo '<tr height="25"><td> </td></tr>' . PHP_EOL;
     2343                        echo '<tr height="25"><td> </td></tr>' . "\n";
    23052344                        // 1.2.5: use wp_kses_post on setting output with custom allowed HTML
    23062345                        echo wp_kses( $this->setting_row( $option ), $this->allowed_html( $option ) );
    2307                         echo '<tr height="25"><td> </td></tr>' . PHP_EOL;
     2346                        echo '<tr height="25"><td> </td></tr>' . "\n";
    23082347                    }
    23092348                }
     
    23112350                // --- reset/save settings buttons ---
    23122351                // (filtered so removable from any specific tab)
    2313                 $buttons = '<tr height="25"><td> </td></tr>' . PHP_EOL;
    2314                 $buttons .= '<tr><td align="center">' . PHP_EOL;
     2352                $buttons = '<tr height="25"><td> </td></tr>' . "\n";
     2353                $buttons .= '<tr><td align="center">' . "\n";
    23152354                // 1.2.5: remove reset onclick attribute
    2316                 $buttons .= '<input type="button" id="settingsresetbutton" class="button-secondary settings-button" value="' . esc_attr( __( 'Reset Settings' ) ) . '">' . PHP_EOL;
    2317                 $buttons .= '</td><td colspan="3"></td><td align="center">' . PHP_EOL;
    2318                 $buttons .= '<input type="submit" class="button-primary settings-button" value="' . esc_attr( __( 'Save Settings' ) ) . '">' . PHP_EOL;
    2319                 $buttons .= '</td></tr>' . PHP_EOL;
    2320                 $buttons .= '<tr height="25"><td></td></tr>' . PHP_EOL;
     2355                $buttons .= '<input type="button" id="settingsresetbutton" class="button-secondary settings-button" value="' . esc_attr( __( 'Reset Settings' ) ) . '">' . "\n";
     2356                $buttons .= '</td><td colspan="3"></td><td align="center">' . "\n";
     2357                $buttons .= '<input type="submit" class="button-primary settings-button" value="' . esc_attr( __( 'Save Settings' ) ) . '">' . "\n";
     2358                $buttons .= '</td></tr>' . "\n";
     2359                $buttons .= '<tr height="25"><td></td></tr>' . "\n";
    23212360                $buttons = apply_filters( $namespace . '_admin_save_buttons', $buttons, $tab );
    23222361                if ( $buttons ) {
     
    23262365
    23272366                // --- close table ---
    2328                 echo '</table>' . PHP_EOL;
     2367                echo '</table>' . "\n";
    23292368
    23302369                // --- do below tab action ---
     
    23322371
    23332372                // --- close tab output ---
    2334                 echo '</div>' . PHP_EOL;
     2373                echo '</div>' . "\n";
    23352374
    23362375                $i++;
     
    23382377
    23392378            // --- close wrapbox ---
    2340             echo '</div></div>' . PHP_EOL;
     2379            echo '</div></div>' . "\n";
    23412380
    23422381            // --- close settings form ---
    2343             echo '</form>' . PHP_EOL;
     2382            echo '</form>' . "\n";
    23442383
    23452384            // --- enqueue settings resources ---
     
    24992538
    25002539            // --- prepare row output ---
    2501             $row = '<tr class="settings-row">' . PHP_EOL;
    2502 
    2503             $row .= '<td class="settings-label">' . $option['label'] . PHP_EOL;
     2540            $row = '<tr class="settings-row">' . "\n";
     2541
     2542            $row .= '<td class="settings-label">' . $option['label'] . "\n";
    25042543            if ( 'multiselect' == $type ) {
    2505                 $row .= '<br><span>' . esc_html( __( 'Use Ctrl and Click to Select' ) ) . '</span>' . PHP_EOL;
    2506             }
    2507             $row .= '</td><td width="25"></td>' . PHP_EOL;
     2544                $row .= '<br><span>' . esc_html( __( 'Use Ctrl and Click to Select' ) ) . '</span>' . "\n";
     2545            }
     2546            $row .= '</td><td width="25"></td>' . "\n";
    25082547
    25092548            // 1.0.9: added multiple cell spanning note type
    25102549            if ( ( 'note' == $type ) || ( 'info' == $type ) || ( 'helper' == $type ) ) {
    25112550
    2512                 $row .= '<td class="settings-helper" colspan="3">' . PHP_EOL;
     2551                $row .= '<td class="settings-helper" colspan="3">' . "\n";
    25132552                if ( isset( $option['helper'] ) ) {
    25142553                    $row .= $option['helper'];
    25152554                }
    2516                 $row .= '</td>' . PHP_EOL;
     2555                $row .= '</td>' . "\n";
    25172556
    25182557            } else {
     
    25512590                        if ( isset( $pro_link ) ) {
    25522591                            // 1.2.2: change text from Pro details
    2553                             $row .= '<a href="' . esc_url( $pro_link ) . '"' . $pro_target . '>' . esc_html( __( 'Details' ) ) . '</a>' . PHP_EOL;
     2592                            // 1.3.0: add hash link anchor for Pro feature options
     2593                            $option_anchor = str_replace( '_', '-', $option['key'] );
     2594                            $row .= '<a href="' . esc_url( $pro_link ) . '#' . esc_attr( $option_anchor ) . '"' . $pro_target . '>' . esc_html( __( 'Details' ) ) . '</a>' . "\n";
    25542595                        }
    25552596                    } else {
    25562597                        $row .= esc_html( __( 'Coming soon in Pro version!' ) );
    25572598                    }
    2558                     $row .= '</td>' . PHP_EOL;
     2599                    $row .= '</td>' . "\n";
    25592600
    25602601                } else {
    25612602
    2562                     $row .= '<td class="settings-input">' . PHP_EOL;
     2603                    $row .= '<td class="settings-input">' . "\n";
    25632604
    25642605                    // --- maybe prepare special options ---
     
    25692610
    25702611                            $posttype = strtolower( substr( $option['options'], 0, 4 ) );
    2571                             if ( ( ( 'page' == $posttype ) && !isset( $pageoptions ) )
    2572                                 || ( ( 'post' == $posttype ) && !isset( $postoptions ) ) ) {
     2612                            if ( ( ( 'page' == $posttype ) && !isset( $pageoptions ) ) || ( ( 'post' == $posttype ) && !isset( $postoptions ) ) ) {
     2613
    25732614                                global $wpdb;
    2574                                 $query = "SELECT ID,post_title,post_status FROM " . $wpdb->prefix . "posts";
    2575                                 $query .= " WHERE post_type = %s AND post_status != 'auto-draft'";
    2576                                 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    2577                                 $query = $wpdb->prepare( $query, $posttype );
    2578                                 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    2579                                 $results = $wpdb->get_results( $query, ARRAY_A );
     2615                                $results = $wpdb->get_results( $wpdb->prepare( "SELECT ID,post_title,post_status FROM " . $wpdb->prefix . "posts WHERE post_type = %s AND post_status != 'auto-draft'", $posttype ), ARRAY_A );
    25802616
    25812617                                // 1.2.7: fix by moving page/post options variable here
    2582                                 $pageoptions = $postoptions = array( '' => '' );
     2618                                // 1.3.0: check separately to avoid overwriting existing options
     2619                                if ( !isset( $pageoptions ) ) {
     2620                                    $pageoptions = array( '' => '' );
     2621                                }
     2622                                if ( !isset( $postoptions ) ) {
     2623                                    $postoptions = array( '' => '' );
     2624                                }
    25832625                                if ( $results && ( count( $results ) > 0 ) ) {
    25842626                                    foreach ( $results as $result ) {
     
    26562698                            }
    26572699                            $useroptions = array( '' => '' );
     2700
    26582701                            global $wpdb;
    2659                             $query = "SELECT ID,user_login,display_name FROM " . $wpdb->prefix . "users";
    26602702                            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    2661                             $results = $wpdb->get_results( $query, ARRAY_A );
     2703                            $results = $wpdb->get_results( "SELECT ID,user_login,display_name FROM " . $wpdb->prefix . "users", ARRAY_A );
    26622704                            if ( $results && ( count( $results ) > 0 ) ) {
    26632705                                foreach ( $results as $result ) {
     
    26892731                        $checked = ( $setting == $option['value'] ) ? ' checked="checked"' : '';
    26902732                        $row .= '<label for="' . esc_attr( $name ) . '" class="setting-toggle">';
    2691                         $row .= '<input type="checkbox" name="' . esc_attr( $name ) . '" class="setting-toggle" value="' . esc_attr( $option['value'] ) . '"' . $checked . '>' . PHP_EOL;
    2692                         $row .= '<span class="setting-slider round"></span>' . PHP_EOL;
    2693                         $row .= '</label>' . PHP_EOL;
     2733                        $row .= '<input type="checkbox" name="' . esc_attr( $name ) . '" class="setting-toggle" value="' . esc_attr( $option['value'] ) . '"' . $checked . '>' . "\n";
     2734                        $row .= '<span class="setting-slider round"></span>' . "\n";
     2735                        $row .= '</label>' . "\n";
    26942736                        if ( isset( $option['suffix'] ) ) {
    26952737                            $row .= ' ' . $option['suffix'];
     
    27042746                        }
    27052747                        $checked = ( $setting == $option['value'] ) ? ' checked="checked"' : '';
    2706                         $row .= '<input type="checkbox" name="' . esc_attr( $name ) . '" class="setting-checkbox" value="' . esc_attr( $option['value'] ) . '"' . $checked . '>' . PHP_EOL;
     2748                        $row .= '<input type="checkbox" name="' . esc_attr( $name ) . '" class="setting-checkbox" value="' . esc_attr( $option['value'] ) . '"' . $checked . '>' . "\n";
    27072749                        if ( isset( $option['suffix'] ) ) {
    27082750                            $row .= ' ' . $option['suffix'];
     
    27182760                                $checked = ' checked="checked"';
    27192761                            }
    2720                             $checkboxes[] = '<input type="checkbox" name="' . esc_attr( $name ) . "-" . esc_attr( $key ) . '" class="setting-checkbox" value="yes"' . $checked . '> ' . esc_html( $label ) . PHP_EOL;
     2762                            $checkboxes[] = '<input type="checkbox" name="' . esc_attr( $name ) . "-" . esc_attr( $key ) . '" class="setting-checkbox" value="yes"' . $checked . '> ' . esc_html( $label ) . "\n";
    27212763                        }
    27222764                        $row .= implode( '<br>', $checkboxes );
     
    27282770                        foreach ( $option['options'] as $value => $label ) {
    27292771                            $checked = ( $setting == $value ) ? ' checked="checked"' : '';
    2730                             $radios[] = '<input type="radio" class="setting-radio" name="' . esc_attr( $name ) . "' value='" . esc_attr( $value ) . '"' . $checked . '> ' . esc_html( $label ) . PHP_EOL;
     2772                            $radios[] = '<input type="radio" class="setting-radio" name="' . esc_attr( $name ) . "' value='" . esc_attr( $value ) . '"' . $checked . '> ' . esc_html( $label ) . "\n";
    27312773                        }
    27322774                        $row .= implode( '<br>', $radios );
     
    27352777
    27362778                        // --- select dropdown ---
    2737                         $row .= '<select class="setting-select" name="' . esc_attr( $name ) . '">' . PHP_EOL;
     2779                        $row .= '<select class="setting-select" name="' . esc_attr( $name ) . '">' . "\n";
    27382780                        foreach ( $option['options'] as $value => $label ) {
    27392781                            // 1.0.9: support option grouping (set unique key containing OPTGROUP-)
    27402782                            if ( strstr( $value, '*OPTGROUP*' ) ) {
    2741                                 $row .= '<optgroup label="' . esc_attr( $label ) . '">' . esc_html( $label ) . '</optgroup>' . PHP_EOL;
     2783                                $row .= '<optgroup label="' . esc_attr( $label ) . '">' . esc_html( $label ) . '</optgroup>' . "\n";
    27422784                            } else {
    27432785                                // 1.1.3: remove strict value checking
     
    27462788                                    $row .= ' selected="selected"';
    27472789                                }
    2748                                 $row .= '>' . esc_html( $label ) . '</option>' . PHP_EOL;
     2790                                $row .= '>' . esc_html( $label ) . '</option>' . "\n";
    27492791                            }
    27502792                        }
     
    27572799
    27582800                        // --- multiselect dropdown ---
    2759                         $row .= '<select multiple="multiple" class="setting-select" name="' . esc_attr( $name ) . '[]">' . PHP_EOL;
     2801                        $row .= '<select multiple="multiple" class="setting-select" name="' . esc_attr( $name ) . '[]">' . "\n";
    27602802                        foreach ( $option['options'] as $value => $label ) {
    27612803                            if ( '' != $value ) {
    27622804                                // 1.1.3: check for OPTGROUP instead of *OPTGROUP*
    27632805                                if ( strstr( $value, 'OPTGROUP' ) ) {
    2764                                     $row .= '<optgroup label="' . esc_attr( $label ) . '">' . PHP_EOL;
     2806                                    $row .= '<optgroup label="' . esc_attr( $label ) . '">' . "\n";
    27652807                                } else {
    2766                                     if ( is_array( $setting ) && in_array( $value, $setting ) ) {
    2767                                         $selected = ' selected="selected"';
    2768                                     } else {
    2769                                         $selected = '';
    2770                                     }
    2771                                     $row .= '<option value="' . esc_attr( $value ) . '"' . $selected . ">" . esc_html( $label ) . '</option>' . PHP_EOL;
     2808                                    $selected = ( is_array( $setting ) && in_array( $value, $setting ) ) ? ' selected="selected"' : '';
     2809                                    $row .= '<option value="' . esc_attr( $value ) . '"' . $selected . ">" . esc_html( $label ) . '</option>' . "\n";
    27722810                                }
    27732811                            }
     
    27932831                        }
    27942832                        // 1.1.7: fix to attribute quoting output
    2795                         $row .= '<input type="text" name="' . esc_attr( $name ) . '" class="' . esc_attr( $class ) . '" value="' . esc_attr( $setting ) . '" placeholder="' . esc_attr( $placeholder ) . '">' . PHP_EOL;
     2833                        $row .= '<input type="text" name="' . esc_attr( $name ) . '" class="' . esc_attr( $class ) . '" value="' . esc_attr( $setting ) . '" placeholder="' . esc_attr( $placeholder ) . '">' . "\n";
    27962834                        if ( isset( $option['suffix'] ) ) {
    27972835                            $row .= ' ' . $option['suffix'];
     
    28122850                        }
    28132851                        // 1.2.4: added missing esc_textarea on value
    2814                         $row .= '<textarea class="setting-textarea" name="' . esc_attr( $name ) . '" rows="' . esc_attr( $rows ) . '" placeholder="' . esc_attr( $placeholder ) . '">' . esc_textarea( $setting ) . '</textarea>' . PHP_EOL;
     2852                        $row .= '<textarea class="setting-textarea" name="' . esc_attr( $name ) . '" rows="' . esc_attr( $rows ) . '" placeholder="' . esc_attr( $placeholder ) . '">' . esc_textarea( $setting ) . '</textarea>' . "\n";
    28152853
    28162854                    } elseif ( ( 'numeric' == $type ) || ( 'number' == $type ) ) {
     
    28402878
    28412879                        // 1.1.7: remove esc_js from onclick attributes
    2842                         // $onclickdown = "plugin_panel_number_step('down', '" . esc_attr( $name ) . "', " . esc_attr( $min ) . ", " . esc_attr( $max ) . ", " . esc_attr( $step ) . ");" . PHP_EOL;
    2843                         // $row .= '<input class="setting-button button-secondary" type="button" value="-" onclick="' . $onclickdown . '">' . PHP_EOL;
    2844                         $row .= '<input class="number-button number-down-button setting-button button-secondary" type="button" value="-" data="' . esc_attr( $name ) . '">' . PHP_EOL;
     2880                        // $onclickdown = "plugin_panel_number_step('down', '" . esc_attr( $name ) . "', " . esc_attr( $min ) . ", " . esc_attr( $max ) . ", " . esc_attr( $step ) . ");" . "\n";
     2881                        // $row .= '<input class="setting-button button-secondary" type="button" value="-" onclick="' . $onclickdown . '">' . "\n";
     2882                        $row .= '<input class="number-button number-down-button setting-button button-secondary" type="button" value="-" data="' . esc_attr( $name ) . '">' . "\n";
    28452883                        if ( isset( $option['prefix'] ) ) {
    28462884                            $row .= ' ' . $option['prefix'];
    28472885                        }
    28482886                        $data = esc_attr( $min ) . "," . esc_attr( $max ) . "," . esc_attr( $step );
    2849                         $row .= '<input id="number-input-' . esc_attr( $name ) . '" class="setting-numeric" type="text" name="' . esc_attr( $name ) . '" value="' . esc_attr( $setting ) . '" placeholder="' . esc_attr( $placeholder ) . '" data="' . esc_attr( $data ) . '">' . PHP_EOL;
     2887                        $row .= '<input id="number-input-' . esc_attr( $name ) . '" class="setting-numeric" type="text" name="' . esc_attr( $name ) . '" value="' . esc_attr( $setting ) . '" placeholder="' . esc_attr( $placeholder ) . '" data="' . esc_attr( $data ) . '">' . "\n";
    28502888                        if ( isset( $option['suffix'] ) ) {
    28512889                            $row .= ' ' . $option['suffix'];
    28522890                        }
    2853                         // $onclickup = "plugin_panel_number_step('up', '" . esc_attr( $name ) . "', " . esc_attr( $min ) . ", " . esc_attr( $max ) . ", " . esc_attr( $step ) . ");" . PHP_EOL;
    2854                         // $row .= '<input class="setting-button button-secondary" type="button" value="+" onclick="' . $onclickup . '">' . PHP_EOL;
    2855                         $row .= '<input class="number-button number-up-button setting-button button-secondary" type="button" value="+" data="' . esc_attr( $name ) . '">' . PHP_EOL;
     2891                        // $onclickup = "plugin_panel_number_step('up', '" . esc_attr( $name ) . "', " . esc_attr( $min ) . ", " . esc_attr( $max ) . ", " . esc_attr( $step ) . ");" . "\n";
     2892                        // $row .= '<input class="setting-button button-secondary" type="button" value="+" onclick="' . $onclickup . '">' . "\n";
     2893                        $row .= '<input class="number-button number-up-button setting-button button-secondary" type="button" value="+" data="' . esc_attr( $name ) . '">' . "\n";
    28562894
    28572895
     
    28672905                        $row .= '<div class="custom-image-container">';
    28682906                        if ( $has_image ) {
    2869                             $row .= '<img src="' . esc_url( $image[0] ) . '" alt="" style="max-width:100%;">' . PHP_EOL;
    2870                         }
    2871                         $row .= '</div>' . PHP_EOL;
     2907                            $row .= '<img src="' . esc_url( $image[0] ) . '" alt="" style="max-width:100%;">' . "\n";
     2908                        }
     2909                        $row .= '</div>' . "\n";
    28722910
    28732911                        // --- add and remove links ---
    28742912                        $upload_link = get_upload_iframe_src( 'image' );
    2875                         $row .= '<p class="hide-if-no-js">' . PHP_EOL;
     2913                        $row .= '<p class="hide-if-no-js">' . "\n";
    28762914                            $hidden = '';
    28772915                            if ( $has_image ) {
    28782916                                $hidden = ' hidden';
    28792917                            }
    2880                             $row .= '<a class="upload-custom-image' . esc_attr( $hidden ) . '" href="' . esc_url( $upload_link ) . '">' . PHP_EOL;
     2918                            $row .= '<a class="upload-custom-image' . esc_attr( $hidden ) . '" href="' . esc_url( $upload_link ) . '">' . "\n";
    28812919                            $row .= esc_html( __( 'Add Image' ) );
    2882                             $row .= '</a>' . PHP_EOL;
     2920                            $row .= '</a>' . "\n";
    28832921
    28842922                            $hidden = '';
     
    28862924                                $hidden = ' hidden';
    28872925                            }
    2888                             $row .= '<a class="delete-custom-image' . esc_attr( $hidden ) . '" href="#">' . PHP_EOL;
     2926                            $row .= '<a class="delete-custom-image' . esc_attr( $hidden ) . '" href="#">' . "\n";
    28892927                            $row .= esc_html( __( 'Remove Image' ) );
    2890                             $row .= '</a>' . PHP_EOL;
    2891                         $row .= '</p>' . PHP_EOL;
     2928                            $row .= '</a>' . "\n";
     2929                        $row .= '</p>' . "\n";
    28922930
    28932931                        // --- hidden input for image ID ---
    2894                         $row .= '<input class="custom-image-id" name="' . esc_attr( $name ) . '" type="hidden" value="' . esc_attr( $setting ) . '">' . PHP_EOL;
     2932                        $row .= '<input class="custom-image-id" name="' . esc_attr( $name ) . '" type="hidden" value="' . esc_attr( $setting ) . '">' . "\n";
    28952933
    28962934                    } elseif ( 'color' == $type ) {
    28972935
    28982936                        // 1.1.7: added color picker field
    2899                         $row .= '<input type="text" class="color-picker" data-default-color="' . esc_attr( $option['default'] ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $setting ) . '">' . PHP_EOL;
     2937                        $row .= '<input type="text" class="color-picker" data-default-color="' . esc_attr( $option['default'] ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $setting ) . '">' . "\n";
    29002938
    29012939                    } elseif ( 'coloralpha' == $type ) {
    29022940
    29032941                        // 1.1.7: added color picker alpha field
    2904                         $row .= '<input type="text" class="color-picker" data-alpha-enabled="true" data-default-color="' . esc_attr( $option['default'] ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $setting ) . '">' . PHP_EOL;
     2942                        $row .= '<input type="text" class="color-picker" data-alpha-enabled="true" data-default-color="' . esc_attr( $option['default'] ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $setting ) . '">' . "\n";
    29052943
    29062944                    }
     
    29112949                // --- setting helper text ---
    29122950                if ( isset( $option['helper'] ) ) {
    2913                     $row .= '<td width="25"></td>' . PHP_EOL;
    2914                     $row .= '<td class="settings-helper">' . esc_html( $option['helper'] ) . '</td>' . PHP_EOL;
    2915                 }
    2916             }
    2917 
    2918             $row .= '</tr>' . PHP_EOL;
     2951                    $row .= '<td width="25"></td>' . "\n";
     2952                    $row .= '<td class="settings-helper">' . esc_html( $option['helper'] ) . '</td>' . "\n";
     2953                }
     2954            }
     2955
     2956            $row .= '</tr>' . "\n";
    29192957
    29202958            // --- settings row spacer ---
    2921             $row .= '<tr class="settings-spacer"><td> </td></tr>' . PHP_EOL;
     2959            $row .= '<tr class="settings-spacer"><td> </td></tr>' . "\n";
    29222960
    29232961            // --- filter and return setting row ---
     
    29442982                        // --- output tab switcher function ---
    29452983                        // 1.2.5: changed function prefix for consistency
    2946                         /* echo "function plugin_panel_display_tab(tab) {" . PHP_EOL;
     2984                        /* echo "function plugin_panel_display_tab(tab) {" . "\n";
    29472985                        foreach ( $tabs as $tab => $label ) {
    2948                             echo "  document.getElementById('" . esc_js( $tab ) . "-tab-button').className = 'settings-tab-button inactive';" . PHP_EOL;
    2949                             echo "  document.getElementById('" . esc_js( $tab ) . "-tab').className = 'settings-tab inactive'; " . PHP_EOL;
    2950                         }
    2951                         echo "  document.getElementById(tab+'-tab-button').className = 'settings-tab-button active';" . PHP_EOL;
    2952                         echo "  document.getElementById(tab+'-tab').className = 'settings-tab active';" . PHP_EOL;
    2953                         echo "  document.getElementById('settings-tab').value = tab;" . PHP_EOL;
    2954                         echo "}" . PHP_EOL; */
     2986                            echo "  document.getElementById('" . esc_js( $tab ) . "-tab-button').className = 'settings-tab-button inactive';" . "\n";
     2987                            echo "  document.getElementById('" . esc_js( $tab ) . "-tab').className = 'settings-tab inactive'; " . "\n";
     2988                        }
     2989                        echo "  document.getElementById(tab+'-tab-button').className = 'settings-tab-button active';" . "\n";
     2990                        echo "  document.getElementById(tab+'-tab').className = 'settings-tab active';" . "\n";
     2991                        echo "  document.getElementById('settings-tab').value = tab;" . "\n";
     2992                        echo "}" . "\n"; */
    29552993
    29562994                        // 1.2.5: use jQuery click function to remove onclick button attributes
    2957                         echo "jQuery('.settings-tab-button').on('click', function() {" . PHP_EOL;
    2958                         echo "  tab = jQuery(this).attr('id').replace('-tab-button','');" . PHP_EOL;
    2959                         echo "  jQuery('.settings-tab,.settings-tab-button').removeClass('active').addClass('inactive');" . PHP_EOL;
    2960                         echo "  jQuery('#'+tab+'-tab,#'+tab+'-tab-button').removeClass('inactive').addClass('active');" . PHP_EOL;
    2961                         echo "  jQuery('#settings-tab').val(tab);" . PHP_EOL;
    2962                         echo "});" . PHP_EOL;
     2995                        echo "jQuery('.settings-tab-button').on('click', function() {" . "\n";
     2996                        echo "  tab = jQuery(this).attr('id').replace('-tab-button','');" . "\n";
     2997                        echo "  jQuery('.settings-tab,.settings-tab-button').removeClass('active').addClass('inactive');" . "\n";
     2998                        echo "  jQuery('#'+tab+'-tab,#'+tab+'-tab-button').removeClass('inactive').addClass('active');" . "\n";
     2999                        echo "  jQuery('#settings-tab').val(tab);" . "\n";
     3000                        echo "});" . "\n";
    29633001
    29643002                    } elseif ( 'settings_reset' == $script ) {
     
    29683006                        // 1.2.5: changed to jQuery click function to remove onclick button attribute
    29693007                        $confirmreset = __( 'Are you sure you want to reset to default settings?' );
    2970                         // echo "function plugin_panel_reset_defaults() {" . PHP_EOL;
    2971                         echo "jQuery('#settingsresetbutton').on('click', function() {" . PHP_EOL;
    2972                         echo "  agree = confirm('" . esc_js( $confirmreset ) . "');" . PHP_EOL;
    2973                         echo "  if (!agree) {return false;}" . PHP_EOL;
    2974                         echo "  document.getElementById('settings-action').value = 'reset';" . PHP_EOL;
    2975                         echo "  document.getElementById('settings-form').submit();" . PHP_EOL;
    2976                         echo "});" . PHP_EOL;
    2977                         // echo "}" . PHP_EOL;
     3008                        // echo "function plugin_panel_reset_defaults() {" . "\n";
     3009                        echo "jQuery('#settingsresetbutton').on('click', function() {" . "\n";
     3010                        echo "  agree = confirm('" . esc_js( $confirmreset ) . "');" . "\n";
     3011                        echo "  if (!agree) {return false;}" . "\n";
     3012                        echo "  document.getElementById('settings-action').value = 'reset';" . "\n";
     3013                        echo "  document.getElementById('settings-form').submit();" . "\n";
     3014                        echo "});" . "\n";
     3015                        // echo "}" . "\n";
    29783016
    29793017                    } elseif ( 'number_step' == $script ) {
     
    29883026                            if ((max !== false) && (newvalue > parseInt(max))) {newvalue = max;}
    29893027                            document.getElementById(id).value = newvalue;
    2990                         }" . PHP_EOL; */
     3028                        }" . "\n"; */
    29913029                        // 1.2.5: replace with jQuery click function to remove onclick attributes
     3030                        // 1.2.9: fix for possible empty value converting to NaN
    29923031                        echo "jQuery('.number-button').on('click', function() {
    29933032                            if (jQuery(this).hasClass('number-up-button')) {multiplier = 1;}
     
    29963035                            data = jQuery('#'+idref).attr('data').split(',');
    29973036                            min = data[0]; max = data[1]; step = data[2];
    2998                             value = parseInt(jQuery('#'+idref).val());
     3037                            value = jQuery('#'+idref).val();
     3038                            if (value == '') {value = 0;} else {value = parseInt(value);}               
    29993039                            newvalue = value + (multiplier * parseInt(step));
    30003040                            if ((min !== false) && (newvalue < parseInt(min))) {newvalue = min;}
    30013041                            if ((max !== false) && (newvalue > parseInt(max))) {newvalue = max;}
    30023042                            jQuery('#'+idref).val(newvalue);
    3003                         });" . PHP_EOL;
     3043                        });" . "\n";
    30043044
    30053045                    } elseif ( 'media_functions' == $script ) {
     
    30523092                            });
    30533093
    3054                         });" . PHP_EOL;
     3094                        });" . "\n";
    30553095
    30563096                    } elseif ( 'colorpicker_init' == $script ) {
    30573097
    30583098                        // --- initialize color pickers ---
    3059                         echo "jQuery(document).ready(function(){" . PHP_EOL;
    3060                         echo "  if (jQuery('.color-picker').length) {jQuery('.color-picker').wpColorPicker();}" . PHP_EOL;
    3061                         echo "});" . PHP_EOL;
     3099                        echo "jQuery(document).ready(function(){" . "\n";
     3100                        echo "  if (jQuery('.color-picker').length) {jQuery('.color-picker').wpColorPicker();}" . "\n";
     3101                        echo "});" . "\n";
    30623102
    30633103                    }
     
    30833123
    30843124            // --- page styles ---
    3085             $styles[] = '#wrapbox {margin-right: 20px;}';
     3125            // 1.2.9: add padding to bottom of settings form
     3126            $styles[] = '#wrapbox {margin-right: 20px; padding-bottom: 20px;}';
    30863127
    30873128            // --- plugin header styles ---
     
    31183159            $styles[] = '.settings-input input.setting-textarea {width:100%;}';
    31193160            $styles[] = '.settings-input select.setting-select {min-width:100px; max-width:100%;}';
    3120 
     3161           
    31213162            // --- toggle input styles ---
    31223163            // Ref: https://www.w3schools.com/howto/howto_css_switch.asp
     
    31473188            $namespace = $this->namespace;
    31483189            $styles = apply_filters( $namespace . '_admin_page_styles', $styles );
    3149             echo "<style>";
    31503190            // 1.2.5: added wp_strip_all_tags to styles output
    3151             echo wp_strip_all_tags( implode( "\n", $styles ) );
    3152             echo "</style>";
     3191            // 1.3.0: use wp_kses_post on styles output
     3192            // echo wp_strip_all_tags( implode( "\n", $styles ) );
     3193            echo "<style>" . wp_kses_post( implode( "\n", $styles ) ) . "</style>";
    31533194
    31543195        }
     
    34693510// =========
    34703511
     3512// == 1.3.0 ==
     3513// - fix for possible page/post options conflict
     3514// - added explicit email option field type
     3515// - added fallback to text option firld type
     3516// - added check if pro slug data is a string
     3517// - added Freemius has_affiliation key
     3518// - added hash link anchor for Pro feature options
     3519
     3520// == 1.2.9 ==
     3521// - fix empty number field converting to NaN value
     3522// - add bottom padding to settings form wrap box
     3523
    34713524// == 1.2.8 ==
    34723525// - fix saving non-alpha colours in coloralpha fields
  • adminsanity/trunk/readme.txt

    r2821022 r3115930  
    44Tags: wordpress admin, admin menu, admin notices, admin bar, cleaner
    55Requires at least: 4.0.0
    6 Tested up to: 6.1
    7 Stable tag: 1.0.2
     6Tested up to: 6.5.5
     7Stable tag: 1.0.3
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    124124== Changelog ==
    125125
     126= 1.0.3 =
     127* Improved: do not load Menu/Notices on Block Editor pages
     128* Fixed: removed conflicting postbox class on notifications box
     129* Admin Menu: changed expanded menu autoload to on-demand load
     130* Admin Menu: keep menu positions for top WordPress.Com items
     131* Admin Bar: fix to conflict with post type template edit pages
     132* Admin Bar: auto disable bar module on WordPress.Com
     133* Admin Notices: added Elementor Notice class
     134* Admin Notices: do not float right after collapse click
     135
    126136= 1.0.2 =
    127137* Updates: Plugin Panel (1.2.8)
Note: See TracChangeset for help on using the changeset viewer.