Make WordPress Core


Ignore:
Timestamp:
02/06/2024 11:44:09 PM (5 months ago)
Author:
costdev
Message:

Upgrade/Install: Introduce Plugin Dependencies.

Introduces a new "Requires Plugins" plugin header so that plugin developers can list the slugs of the plugins theirs depends on.

This will inform users of the requirements, and provide links to the WordPress.org Plugins Repository that they can click to install and activate the dependencies first.

Plugins whose requirements are not met cannot be installed or activated, and they will be deactivated automatically if their requirements become unmet.
Plugins that others rely on cannot be deactivated or deleted until their dependent plugins are deactivated or deleted.

In memory of Alex Mills and Alex King.
WordPress Remembers.

Props ahoereth, afragen, alanfuller, alexkingorg, amykamala, anonymized_10690803, apeatling, ashfame, atimmer, audrasjb, aristath, azaozz, batmoo, beaulebens, blobaugh, bobbingwide, boonebgorges, brianhenryie, chanthaboune, chrisdavidmiles, coolmann, costdev, courane01, danielbachhuber, davidperez, dd32, Denis-de-Bernardy, dingo_d, DJPaul, dougal, DrewAPicture, ethitter, filosofo, georgestephanis, giuseppemazzapica-1, goldenapples, griffinjt, hellofromTonya, husobj, ideag, jarednova, jbobich, jbrinley, jltallon, joedolson, johnciacia, johnjamesjacoby, joppuyo, jsmoriss, karmatosed, kebbet, knutsp, kraftbj, kraftner, kurtpayne, lkraav, logikal16, luisherranz, man4toman, markjaquith, matt, mbijon, megphillips91, mikeschinkel, mordauk, morehawes, mrwweb, mte90, mukesh27, mzaweb, nacin, norcross, nvwd, nwjames, obliviousharmony, ocean90, oglekler, paaljoachim, pauldewouters, pbaylies, pbiron, peterwilsoncc, Philipp15b, poena, pogidude, retlehs, rmccue, ryan, sabreuse, sc0ttkclark, scribu, sereedmedia, SergeyBiryukov, ShaneF, shidouhikari, soean, spacedmonkey, stephenh1988, swissspidy, taylorde, tazotodua, threadi, TimothyBlynJacobs, TJNowell, tollmanz, toscho, tropicalista, Viper007Bond, westi, whiteshadow, williamsba1, wpsmith, ZaneMatthew.
Fixes #22316.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-plugin-install-list-table.php

    r56599 r57545  
    526526            $description = strip_tags( $plugin['short_description'] );
    527527
     528            $description .= $this->get_dependencies_notice( $plugin );
     529
    528530            /**
    529531             * Filters the plugin card description on the Add Plugins screen.
     
    556558            $action_links = array();
    557559
    558             if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) {
    559                 $status = install_plugin_install_status( $plugin );
    560 
    561                 switch ( $status['status'] ) {
    562                     case 'install':
    563                         if ( $status['url'] ) {
    564                             if ( $compatible_php && $compatible_wp ) {
    565                                 $action_links[] = sprintf(
    566                                     '<a class="install-now button" data-slug="%s" href="%s" aria-label="%s" data-name="%s">%s</a>',
    567                                     esc_attr( $plugin['slug'] ),
    568                                     esc_url( $status['url'] ),
    569                                     /* translators: %s: Plugin name and version. */
    570                                     esc_attr( sprintf( _x( 'Install %s now', 'plugin' ), $name ) ),
    571                                     esc_attr( $name ),
    572                                     __( 'Install Now' )
    573                                 );
    574                             } else {
    575                                 $action_links[] = sprintf(
    576                                     '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
    577                                     _x( 'Cannot Install', 'plugin' )
    578                                 );
    579                             }
    580                         }
    581                         break;
    582 
    583                     case 'update_available':
    584                         if ( $status['url'] ) {
    585                             if ( $compatible_php && $compatible_wp ) {
    586                                 $action_links[] = sprintf(
    587                                     '<a class="update-now button aria-button-if-js" data-plugin="%s" data-slug="%s" href="%s" aria-label="%s" data-name="%s">%s</a>',
    588                                     esc_attr( $status['file'] ),
    589                                     esc_attr( $plugin['slug'] ),
    590                                     esc_url( $status['url'] ),
    591                                     /* translators: %s: Plugin name and version. */
    592                                     esc_attr( sprintf( _x( 'Update %s now', 'plugin' ), $name ) ),
    593                                     esc_attr( $name ),
    594                                     __( 'Update Now' )
    595                                 );
    596                             } else {
    597                                 $action_links[] = sprintf(
    598                                     '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
    599                                     _x( 'Cannot Update', 'plugin' )
    600                                 );
    601                             }
    602                         }
    603                         break;
    604 
    605                     case 'latest_installed':
    606                     case 'newer_installed':
    607                         if ( is_plugin_active( $status['file'] ) ) {
    608                             $action_links[] = sprintf(
    609                                 '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
    610                                 _x( 'Active', 'plugin' )
    611                             );
    612                         } elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) {
    613                             if ( $compatible_php && $compatible_wp ) {
    614                                 $button_text = __( 'Activate' );
    615                                 /* translators: %s: Plugin name. */
    616                                 $button_label = _x( 'Activate %s', 'plugin' );
    617                                 $activate_url = add_query_arg(
    618                                     array(
    619                                         '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ),
    620                                         'action'   => 'activate',
    621                                         'plugin'   => $status['file'],
    622                                     ),
    623                                     network_admin_url( 'plugins.php' )
    624                                 );
    625 
    626                                 if ( is_network_admin() ) {
    627                                     $button_text = __( 'Network Activate' );
    628                                     /* translators: %s: Plugin name. */
    629                                     $button_label = _x( 'Network Activate %s', 'plugin' );
    630                                     $activate_url = add_query_arg( array( 'networkwide' => 1 ), $activate_url );
    631                                 }
    632 
    633                                 $action_links[] = sprintf(
    634                                     '<a href="%1$s" class="button activate-now" aria-label="%2$s">%3$s</a>',
    635                                     esc_url( $activate_url ),
    636                                     esc_attr( sprintf( $button_label, $plugin['name'] ) ),
    637                                     $button_text
    638                                 );
    639                             } else {
    640                                 $action_links[] = sprintf(
    641                                     '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
    642                                     _x( 'Cannot Activate', 'plugin' )
    643                                 );
    644                             }
    645                         } else {
    646                             $action_links[] = sprintf(
    647                                 '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
    648                                 _x( 'Installed', 'plugin' )
    649                             );
    650                         }
    651                         break;
    652                 }
    653             }
     560            $action_links[] = wp_get_plugin_action_button( $name, $plugin, $compatible_php, $compatible_wp );
    654561
    655562            $details_link = self_admin_url(
     
    829736        }
    830737    }
     738
     739    /**
     740     * Returns a notice containing a list of dependencies required by the plugin.
     741     *
     742     * @since 6.5.0
     743     *
     744     * @param array  $plugin_data An array of plugin data. See {@see plugins_api()}
     745     *                            for the list of possible values.
     746     * @return string A notice containing a list of dependencies required by the plugin,
     747     *                or an empty string if none is required.
     748     */
     749    protected function get_dependencies_notice( $plugin_data ) {
     750        if ( empty( $plugin_data['requires_plugins'] ) ) {
     751            return '';
     752        }
     753
     754        $no_name_markup  = '<div class="plugin-dependency"><span class="plugin-dependency-name">%s</span></div>';
     755        $has_name_markup = '<div class="plugin-dependency"><span class="plugin-dependency-name">%s</span> %s</div>';
     756
     757        $dependencies_list = '';
     758        foreach ( $plugin_data['requires_plugins'] as $dependency ) {
     759            $dependency_data = WP_Plugin_Dependencies::get_dependency_data( $dependency );
     760
     761            if (
     762                false !== $dependency_data &&
     763                ! empty( $dependency_data['name'] ) &&
     764                ! empty( $dependency_data['slug'] ) &&
     765                ! empty( $dependency_data['version'] )
     766            ) {
     767                $more_details_link  = $this->get_more_details_link( $dependency_data['name'], $dependency_data['slug'] );
     768                $dependencies_list .= sprintf( $has_name_markup, esc_html( $dependency_data['name'] ), $more_details_link );
     769                continue;
     770            }
     771
     772            $result = plugins_api( 'plugin_information', array( 'slug' => $dependency ) );
     773
     774            if ( ! empty( $result->name ) ) {
     775                $more_details_link  = $this->get_more_details_link( $result->name, $result->slug );
     776                $dependencies_list .= sprintf( $has_name_markup, esc_html( $result->name ), $more_details_link );
     777                continue;
     778            }
     779
     780            $dependencies_list .= sprintf( $no_name_markup, esc_html( $dependency ) );
     781        }
     782
     783        $dependencies_notice = sprintf(
     784            '<div class="plugin-dependencies"><p class="plugin-dependencies-explainer-text">%s</p> %s</div>',
     785            '<strong>' . __( 'Additional plugins are required' ) . '</strong>',
     786            $dependencies_list
     787        );
     788
     789        return $dependencies_notice;
     790    }
     791
     792    /**
     793     * Creates a 'More details' link for the plugin.
     794     *
     795     * @since 6.5.0
     796     *
     797     * @param string $name The plugin's name.
     798     * @param string $slug The plugin's slug.
     799     * @return string The 'More details' link for the plugin.
     800     */
     801    protected function get_more_details_link( $name, $slug ) {
     802        $url = add_query_arg(
     803            array(
     804                'tab'       => 'plugin-information',
     805                'plugin'    => $slug,
     806                'TB_iframe' => 'true',
     807                'width'     => '600',
     808                'height'    => '550',
     809            ),
     810            network_admin_url( 'plugin-install.php' )
     811        );
     812
     813        $more_details_link = sprintf(
     814            '<a href="%1$s" class="more-details-link thickbox open-plugin-details-modal" aria-label="%2$s" data-title="%3$s">%4$s</a>',
     815            esc_url( $url ),
     816            /* translators: %s: Plugin name. */
     817            sprintf( __( 'More information about %s' ), esc_html( $name ) ),
     818            esc_attr( $name ),
     819            __( 'More Details' )
     820        );
     821
     822        return $more_details_link;
     823    }
    831824}
Note: See TracChangeset for help on using the changeset viewer.