strangerstudios / paid-memberships-pro

WordPress membership plugin to restrict access to content and charge recurring subscriptions using Stripe, PayPal, and more. Fully open source. 100% GPL.
https://www.paidmembershipspro.com
Other
458 stars 357 forks source link

PMPRO is aggressively loading its own version of select2 on ALL admin pages #2902

Open zagarskas opened 5 months ago

zagarskas commented 5 months ago

Describe the bug Very simple: PMPRO is aggressively loading its own version of select2 on ALL admin pages.

This creates problems. There are other plugins and themes out there using PRE 4.0 select2, and the newest select2 4.1.1 - a conflict then ensues.

To Reproduce Steps to reproduce the behavior:

  1. install PMPRO
  2. write custom code for your own theme or plugin that uses another version of select2
  3. watch the PMPRO version of select2 load into the page and cause issues

Screenshots src="/wp-content/plugins/paid-memberships-pro/js/pmpro-admin.js" image

Expected behavior this ambiguous handle: "select2-js" would better be "pmpro_admin-select2-js" so we can identify and dequeue it. Also ideal: not loading PMPRO's version of select2 on every wp-admin page would be courteous

consider that some of us are using this: Select2 4.1.1-rc.2 | https://github.com/select2/select2/blob/master/LICENSE.md and have modified the core to patch this issue -- Added non-passive event listener to a scroll-blocking event. https://github.com/angular/components/issues/4221

Isolating the problem (mark completed items with an [x]):

WordPress Environment

``` n/a ```
zagarskas commented 5 months ago

Digging into this some more, check out this nicely restricted usage: plugins\paid-memberships-pro\includes\scripts.php

    // Enqueue select2 on front end and user profiles
    if( pmpro_is_checkout() || 
        ! empty( $_REQUEST['level'] ) ||
        ! empty( $pmpro_level ) ||
        ( class_exists("Theme_My_Login") && method_exists('Theme_My_Login', 'is_tml_page') && Theme_My_Login::is_tml_page("profile") ) ||
        ( isset( $pmpro_pages['member_profile_edit'] ) && is_page( $pmpro_pages['member_profile_edit'] ) ) ) {
        wp_enqueue_style( 'select2', plugins_url('css/select2.min.css', dirname(__FILE__)), '', '4.0.3', 'screen' );
        wp_enqueue_script( 'select2', plugins_url('js/select2.min.js', dirname(__FILE__)), array( 'jquery' ), '4.0.3' );
    }

Its good that member_profile_edit and member_profile_edit are limited.

But on the back end Forcing select2 into all admin pages is too aggressive. For example:

See: pmpro_admin_enqueue_scripts()

add_action( 'admin_enqueue_scripts', 'pmpro_admin_enqueue_scripts' );

/**
 * Enqueue admin JavaScript and CSS
 */
function pmpro_admin_enqueue_scripts() {
    // Enqueue Select2.  
    wp_register_script( 'select2',
                        plugins_url( 'js/select2.min.js', dirname(__FILE__) ),
                        array( 'jquery', 'jquery-ui-sortable' ),
                        '4.0.3' );
    wp_enqueue_style( 'select2', plugins_url('css/select2.min.css', dirname(__FILE__)), '', '4.0.3', 'screen' );
    wp_enqueue_script( 'select2' );

There is no consideration at all here for loading select2 only onto PMPRO pages.

I would propose the use of $screen = get_current_screen(); to at least determine the core PMPRO pages, and then considerately load select2 [only there, where it belongs, in PMPRO admin pages]

zagarskas commented 5 months ago

Currently, here is the patch I am using

   add_action( 'admin_enqueue_scripts', array( $this, 'select2_fixes' ), 100 );
            public function select2_fixes() {
                if(class_exists("PMPro_Field")) {
                    $screen = get_current_screen();
                    if (!str_contains($screen->id, 'pmpro')) { 
                          wp_deregister_script( 'select2' );
                          wp_dequeue_script( 'select2' );
                          wp_deregister_style( 'select2' );
                          wp_dequeue_style( 'select2' );
                    }
                }
            }

which seems legit for now (to stop client-yelling :( )... but, what if I am removing select2 when its needed?

I think it would be wonderful if something like this was tacked on here: here: \plugins\paid-memberships-pro\includes\scripts.php more specifically: add_action( 'admin_enqueue_scripts', 'pmpro_admin_enqueue_scripts' ); Lines 104-113

/** 
 * Enqueue admin JavaScript and CSS
 * What if you only did this when its a PMPro screen?
 */
function pmpro_admin_enqueue_scripts() {
    // Enqueue Select2.  - but... only where it belongs

    $screen = get_current_screen(); // seems like all pmpro screen say so...
    if (str_contains($screen->id, 'pmpro')) {  //which is nice...
        wp_register_script( 'pmpro_admin-select2', plugins_url( 'js/select2.min.js', dirname(__FILE__) ), array( 'jquery', 'jquery-ui-sortable' ), '4.0.3' );
        wp_enqueue_style( 'pmpro_admin-select2', plugins_url('css/select2.min.css', dirname(__FILE__)), '', '4.0.3', 'screen' );
        wp_enqueue_script( 'pmpro_admin-select2' );
    }

or... tack on a dependency for wp_register_script( 'pmpro_admin', might be a great quick idea!

creador-dev commented 1 month ago

Same issue here. Please resolve it. Why do you guys need to load scripts on every page is there any reason?