diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-admin/includes/plugin-install.php --- a/wp/wp-admin/includes/plugin-install.php Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-admin/includes/plugin-install.php Fri Sep 05 18:40:08 2025 +0200 @@ -174,7 +174,8 @@ if ( $ssl && is_wp_error( $request ) ) { if ( ! wp_is_json_request() ) { - trigger_error( + wp_trigger_error( + __FUNCTION__, sprintf( /* translators: %s: Support forums URL. */ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ), @@ -316,18 +317,23 @@ */ function install_search_form( $deprecated = true ) { $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; - $term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : ''; + $term = isset( $_REQUEST['s'] ) ? urldecode( wp_unslash( $_REQUEST['s'] ) ) : ''; ?>
- + + + - - 'search-submit' ) ); ?>

-
+ - + - +
' . __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the WordPress Plugin Directory or upload a plugin in .zip format by clicking the button at the top of this page.' ) . '

', + '

' . __( 'Plugins extend and expand the functionality of WordPress. You may install plugins in the WordPress Plugin Directory right from here, or upload a plugin in .zip format by clicking the button at the top of this page.' ) . '

', __( 'https://wordpress.org/plugins/' ) ); break; @@ -471,8 +482,10 @@ } } else { $key = array_keys( $installed_plugin ); - // Use the first plugin regardless of the name. - // Could have issues for multiple plugins in one directory if they share different version numbers. + /* + * Use the first plugin regardless of the name. + * Could have issues for multiple plugins in one directory if they share different version numbers. + */ $key = reset( $key ); $update_file = $api->slug . '/' . $key; @@ -800,37 +813,54 @@ $tested_wp = ( empty( $api->tested ) || version_compare( get_bloginfo( 'version' ), $api->tested, '<=' ) ); if ( ! $compatible_php ) { - echo '

'; - _e( 'Error: This plugin requires a newer version of PHP.' ); + $compatible_php_notice_message = '

'; + $compatible_php_notice_message .= __( 'Error: This plugin requires a newer version of PHP.' ); + if ( current_user_can( 'update_php' ) ) { - printf( + $compatible_php_notice_message .= sprintf( /* translators: %s: URL to Update PHP page. */ ' ' . __( 'Click here to learn more about updating PHP.' ), esc_url( wp_get_update_php_url() ) - ); - - wp_update_php_annotation( '

', '' ); + ) . wp_update_php_annotation( '

', '', false ); } else { - echo '

'; + $compatible_php_notice_message .= '

'; } - echo '
'; + + wp_admin_notice( + $compatible_php_notice_message, + array( + 'type' => 'error', + 'additional_classes' => array( 'notice-alt' ), + 'paragraph_wrap' => false, + ) + ); } if ( ! $tested_wp ) { - echo '

'; - _e( 'Warning: This plugin has not been tested with your current version of WordPress.' ); - echo '

'; + wp_admin_notice( + __( 'Warning: This plugin has not been tested with your current version of WordPress.' ), + array( + 'type' => 'warning', + 'additional_classes' => array( 'notice-alt' ), + ) + ); } elseif ( ! $compatible_wp ) { - echo '

'; - _e( 'Error: This plugin requires a newer version of WordPress.' ); + $compatible_wp_notice_message = __( 'Error: This plugin requires a newer version of WordPress.' ); if ( current_user_can( 'update_core' ) ) { - printf( + $compatible_wp_notice_message .= sprintf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( 'Click here to update WordPress.' ), - self_admin_url( 'update-core.php' ) + esc_url( self_admin_url( 'update-core.php' ) ) ); } - echo '

'; + + wp_admin_notice( + $compatible_wp_notice_message, + array( + 'type' => 'error', + 'additional_classes' => array( 'notice-alt' ), + ) + ); } foreach ( (array) $api->sections as $section_name => $content ) { @@ -850,43 +880,166 @@ echo "\n"; // #plugin-information-scrollable echo "\n"; + + wp_print_request_filesystem_credentials_modal(); + wp_print_admin_notice_templates(); + + iframe_footer(); + exit; +} + +/** + * Gets the markup for the plugin install action button. + * + * @since 6.5.0 + * + * @param string $name Plugin name. + * @param array|object $data { + * An array or object of plugin data. Can be retrieved from the API. + * + * @type string $slug The plugin slug. + * @type string[] $requires_plugins An array of plugin dependency slugs. + * @type string $version The plugin's version string. Used when getting the install status. + * } + * @param bool $compatible_php The result of a PHP compatibility check. + * @param bool $compatible_wp The result of a WP compatibility check. + * @return string The markup for the dependency row button. An empty string if the user does not have capabilities. + */ +function wp_get_plugin_action_button( $name, $data, $compatible_php, $compatible_wp ) { + $button = ''; + $data = (object) $data; + $status = install_plugin_install_status( $data ); + $requires_plugins = $data->requires_plugins ?? array(); + + // Determine the status of plugin dependencies. + $installed_plugins = get_plugins(); + $active_plugins = get_option( 'active_plugins', array() ); + $plugin_dependencies_count = count( $requires_plugins ); + $installed_plugin_dependencies_count = 0; + $active_plugin_dependencies_count = 0; + foreach ( $requires_plugins as $dependency ) { + foreach ( array_keys( $installed_plugins ) as $installed_plugin_file ) { + if ( str_contains( $installed_plugin_file, '/' ) && explode( '/', $installed_plugin_file )[0] === $dependency ) { + ++$installed_plugin_dependencies_count; + } + } + + foreach ( $active_plugins as $active_plugin_file ) { + if ( str_contains( $active_plugin_file, '/' ) && explode( '/', $active_plugin_file )[0] === $dependency ) { + ++$active_plugin_dependencies_count; + } + } + } + $all_plugin_dependencies_installed = $installed_plugin_dependencies_count === $plugin_dependencies_count; + $all_plugin_dependencies_active = $active_plugin_dependencies_count === $plugin_dependencies_count; + + if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) { switch ( $status['status'] ) { case 'install': if ( $status['url'] ) { - if ( $compatible_php && $compatible_wp ) { - echo '' . __( 'Install Now' ) . ''; + if ( $compatible_php && $compatible_wp && $all_plugin_dependencies_installed && ! empty( $data->download_link ) ) { + $button = sprintf( + '%s', + esc_attr( $data->slug ), + esc_url( $status['url'] ), + /* translators: %s: Plugin name and version. */ + esc_attr( sprintf( _x( 'Install %s now', 'plugin' ), $name ) ), + esc_attr( $name ), + _x( 'Install Now', 'plugin' ) + ); } else { - printf( - '', - _x( 'Cannot Install', 'plugin' ) + $button = sprintf( + '', + _x( 'Install Now', 'plugin' ) ); } } break; + case 'update_available': if ( $status['url'] ) { - if ( $compatible_php ) { - echo '' . __( 'Install Update Now' ) . ''; + if ( $compatible_php && $compatible_wp ) { + $button = sprintf( + '%s', + esc_attr( $status['file'] ), + esc_attr( $data->slug ), + esc_url( $status['url'] ), + /* translators: %s: Plugin name and version. */ + esc_attr( sprintf( _x( 'Update %s now', 'plugin' ), $name ) ), + esc_attr( $name ), + _x( 'Update Now', 'plugin' ) + ); } else { - printf( - '', - _x( 'Cannot Update', 'plugin' ) + $button = sprintf( + '', + _x( 'Update Now', 'plugin' ) ); } } break; + + case 'latest_installed': case 'newer_installed': - /* translators: %s: Plugin version. */ - echo '' . sprintf( __( 'Newer Version (%s) Installed' ), esc_html( $status['version'] ) ) . ''; - break; - case 'latest_installed': - echo '' . __( 'Latest Version Installed' ) . ''; + if ( is_plugin_active( $status['file'] ) ) { + $button = sprintf( + '', + _x( 'Active', 'plugin' ) + ); + } elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) { + if ( $compatible_php && $compatible_wp && $all_plugin_dependencies_active ) { + $button_text = _x( 'Activate', 'plugin' ); + /* translators: %s: Plugin name. */ + $button_label = _x( 'Activate %s', 'plugin' ); + $activate_url = add_query_arg( + array( + '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ), + 'action' => 'activate', + 'plugin' => $status['file'], + ), + network_admin_url( 'plugins.php' ) + ); + + if ( is_network_admin() ) { + $button_text = _x( 'Network Activate', 'plugin' ); + /* translators: %s: Plugin name. */ + $button_label = _x( 'Network Activate %s', 'plugin' ); + $activate_url = add_query_arg( array( 'networkwide' => 1 ), $activate_url ); + } + + $button = sprintf( + '%6$s', + esc_url( $activate_url ), + esc_attr( $name ), + esc_attr( $data->slug ), + esc_attr( $status['file'] ), + esc_attr( sprintf( $button_label, $name ) ), + $button_text + ); + } else { + $button = sprintf( + '', + is_network_admin() ? _x( 'Network Activate', 'plugin' ) : _x( 'Activate', 'plugin' ) + ); + } + } else { + $button = sprintf( + '', + _x( 'Installed', 'plugin' ) + ); + } break; } } - echo "\n"; - iframe_footer(); - exit; + return $button; }