' . $annotation . ''; } } // Get the upgrade notice for the new plugin version. if ( isset( $plugin_data->update->upgrade_notice ) ) { $upgrade_notice = '' . wp_strip_all_tags( $plugin_data->update->upgrade_notice ); } else { $upgrade_notice = ''; } $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $plugin_data->update->slug . '§ion=changelog&TB_iframe=true&width=640&height=662' ); $details = sprintf( '%3$s', esc_url( $details_url ), /* translators: 1: Plugin name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $plugin_data->update->new_version ) ), /* translators: %s: Plugin version. */ sprintf( __( 'View version %s details.' ), $plugin_data->update->new_version ) ); $checkbox_id = 'checkbox_' . md5( $plugin_name ); // Plugin template properties. There is no compatible_wp property passed here. $plugin_processed[ $plugin_file ] = array( 'plugin_file' => esc_attr( $plugin_file ), 'name' => esc_attr( $plugin_name ), 'checkbox_id' => esc_attr( 'checkbox_' . md5( $plugin_name ) ), 'icon' => et_core_intentionally_unescaped( $icon, 'html' ), 'version' => esc_attr( $plugin_version ), 'new_version' => esc_attr( $plugin_data->update->new_version ), 'compatible_php' => $compatible_php, 'compat' => et_core_intentionally_unescaped( $compat, 'html' ), 'upgrade_notice' => et_core_intentionally_unescaped( $upgrade_notice, 'html' ), 'details' => et_core_intentionally_unescaped( $details, 'html' ), ); } return $plugin_processed; } /** * Get themes data for Update Core page. * * @since 4.7.0 * * @return array */ public function get_update_core_themes_data() { $theme_updates = get_theme_updates(); $theme_processed = array(); // Bail early if there is no theme updates. if ( empty( $theme_updates ) ) { return array(); } foreach ( $theme_updates as $stylesheet => $theme ) { // a. Check compatibility. $requires_wp = et_()->array_get( $theme->update, 'requires', null ); $requires_php = et_()->array_get( $theme->update, 'requires_php', null ); $compatible_wp = is_wp_version_compatible( $requires_wp ); $compatible_php = is_php_version_compatible( $requires_php ); // b. Process compatibility warning text. $compat = ''; if ( ! $compatible_wp && ! $compatible_php ) { $compat .= '' . __( 'This update doesn’t work with your versions of WordPress and PHP.' ) . ' '; if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { $compat .= sprintf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ __( 'Please update WordPress, and then learn more about updating PHP.' ), esc_url( self_admin_url( 'update-core.php' ) ), esc_url( wp_get_update_php_url() ) ); $annotation = wp_get_update_php_annotation(); if ( $annotation ) { $compat .= '
' . $annotation . ''; } } elseif ( current_user_can( 'update_core' ) ) { $compat .= sprintf( /* translators: %s: URL to WordPress Updates screen. */ __( 'Please update WordPress.' ), esc_url( self_admin_url( 'update-core.php' ) ) ); } elseif ( current_user_can( 'update_php' ) ) { $compat .= sprintf( /* translators: %s: URL to Update PHP page. */ __( 'Learn more about updating PHP.' ), esc_url( wp_get_update_php_url() ) ); $annotation = wp_get_update_php_annotation(); if ( $annotation ) { $compat .= '
' . $annotation . ''; } } } elseif ( ! $compatible_wp ) { $compat .= '' . __( 'This update doesn’t work with your version of WordPress.' ) . ' '; if ( current_user_can( 'update_core' ) ) { $compat .= sprintf( /* translators: %s: URL to WordPress Updates screen. */ __( 'Please update WordPress.' ), esc_url( self_admin_url( 'update-core.php' ) ) ); } } elseif ( ! $compatible_php ) { $compat .= '' . __( 'This update doesn’t work with your version of PHP.' ) . ' '; if ( current_user_can( 'update_php' ) ) { $compat .= sprintf( /* translators: %s: URL to Update PHP page. */ __( 'Learn more about updating PHP.' ), esc_url( wp_get_update_php_url() ) ); $annotation = wp_get_update_php_annotation(); if ( $annotation ) { $compat .= '
' . $annotation . ''; } } } // Theme template properties. $theme_processed[ $stylesheet ] = array( 'stylesheet' => esc_attr( $stylesheet ), 'name' => esc_attr( $theme->display( 'Name' ) ), 'checkbox_id' => esc_attr( 'checkbox_' . md5( $theme->get( 'Name' ) ) ), 'screenshot' => esc_url( $theme->get_screenshot() ), 'version' => esc_attr( $theme->display( 'Version' ) ), 'new_version' => esc_attr( et_()->array_get( $theme->update, 'new_version', '' ) ), 'compatible_wp' => $compatible_wp, 'compatible_php' => $compatible_php, 'compat' => et_core_esc_previously( $compat ), ); } return $theme_processed; } /** * Enqueue compatibility warning scripts and its local data. * * @since 4.7.0 */ public function enqueue_scripts() { global $pagenow, $wp_customize; // Bail early if the current page is not one of the allowed pages. $allowed_pages = array( 'update-core.php', 'customize.php', 'themes.php', ); if ( ! in_array( $pagenow, $allowed_pages, true ) ) { return; } // Enqueue main scripts. wp_enqueue_script( 'et_compatibility_warning_script', ET_CORE_URL . 'admin/js/compatibility-warning.js', array( 'jquery' ), ET_CORE_VERSION, true ); $compatibility_warning = array(); if ( 'update-core.php' === $pagenow ) { $compatibility_warning['update_core_data'] = array( 'plugins' => self::get_update_core_plugins_data(), 'themes' => self::get_update_core_themes_data(), ); } elseif ( 'themes.php' === $pagenow ) { $compatibility_warning['manage_themes_data'] = true; } elseif ( 'customize.php' === $pagenow ) { // Ensure style.css file exist. $theme_root = $wp_customize->theme()->theme_root; $theme_slug = $wp_customize->theme()->stylesheet; $theme_file = "{$theme_root}/{$theme_slug}/style.css"; // Get WP & PHP compatibility info. $theme_headers = array(); if ( file_exists( $theme_file ) ) { $theme_headers = get_file_data( $theme_file, array( 'RequiresWP' => 'Requires at least', 'RequiresPHP' => 'Requires PHP', ), 'theme' ); } $requires_wp = et_()->array_get( $theme_headers, 'RequiresWP', false ); $requires_php = et_()->array_get( $theme_headers, 'RequiresPHP', false ); // Theme Customizer - Used for disable publish button. $compatibility_warning['customizer_data'] = array( 'compatible_wp' => is_wp_version_compatible( $requires_wp ), 'compatible_php' => is_php_version_compatible( $requires_php ), 'disabled_text' => esc_html_x( 'Cannot Activate', 'theme' ), ); } wp_localize_script( 'et_compatibility_warning_script', 'et_compatibility_warning', $compatibility_warning ); } /** * Overrides table body of plugin updates section. * * The structure is backported from WP 5.5 without any modification. * * @see {list_plugin_updates()} of WP 5.5 * * @since 4.7.0 */ public function overrides_update_core_plugins_table_body() { // Bail early if there is no plugin updates. if ( empty( get_plugin_updates() ) ) { return; } ?> response ) && is_array( $update_plugins->response ) ) { foreach ( $update_plugins->response as $plugin_file => $plugin ) { $requires_php = isset( $plugin->requires_php ) ? $plugin->requires_php : null; $compatible_php = is_php_version_compatible( $requires_php ); // Bail early if the package empty or already compatible with current PHP version. if ( empty( $plugin->package ) || $compatible_php ) { continue; } // Need to remove default action before we can replace it with the new one. remove_action( "after_plugin_row_$plugin_file", 'wp_plugin_update_row', 10, 2 ); add_action( "after_plugin_row_$plugin_file", array( $this, 'plugin_update_row_compatibility_error' ), 10, 2 ); } } } /** * Display plugin update row with error compatibility. * * @see {wp_plugin_update_row()} of WP 5.5 * * @since 4.7.0 * * @param string $file Plugin basename. * @param array $plugin_data Plugin information. */ public function plugin_update_row_compatibility_error( $file, $plugin_data ) { if ( ! is_network_admin() && is_multisite() ) { return; } $update_plugins = get_site_transient( 'update_plugins' ); if ( ! isset( $update_plugins->response[ $file ] ) ) { return; } // a. Plugin response. $response = $update_plugins->response[ $file ]; // b. Plugin name. $plugins_allowedtags = array( 'a' => array( 'href' => array(), 'title' => array(), ), 'abbr' => array( 'title' => array() ), 'acronym' => array( 'title' => array() ), 'code' => array(), 'em' => array(), 'strong' => array(), ); $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags ); // c. Details URL. $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $response->slug . '§ion=changelog&TB_iframe=true&width=600&height=800' ); // d. Active class. if ( is_network_admin() ) { $active_class = is_plugin_active_for_network( $file ) ? ' active' : ''; } else { $active_class = is_plugin_active( $file ) ? ' active' : ''; } /** * Column count. * * @var WP_Plugins_List_Table $wp_list_table */ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table', array( 'screen' => get_current_screen(), ) ); // f. Error text. $update_php_notation = wp_get_update_php_annotation(); $error_text = sprintf( /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number 5: URL to Update PHP page. */ __( 'There is a new version of %1$s available, but it doesn’t work with your version of PHP. View version %4$s details or learn more about updating PHP. %6$s' ), $plugin_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Plugin name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) ), esc_attr( $response->new_version ), esc_url( wp_get_update_php_url() ), // #5 ! empty( $update_php_notation ) ? sprintf( __( '%s' ), $update_php_notation ) : '' ); printf( /* translators: 1: Active class, 2: Update slug, 3: Slug, 4: Plugin file, 5: Column count. */ '
%6$s
' . sprintf( __( 'Learn more about updating PHP.' ), esc_url( wp_get_update_php_url() ) ); $annotation = wp_get_update_php_annotation(); if ( $annotation ) { $php_update_message .= '
' . $annotation . ''; } // Decide whether current plugin is compatible and should be activated or not. $result = true; if ( ! $compatible_wp && ! $compatible_php ) { $result = new WP_Error( 'plugin_wp_php_incompatible', '
' . sprintf( /* translators: 1: Current WordPress version, 2: Current PHP version, 3: Plugin name, 4: Required WordPress version, 5: Required PHP version. */ _x( 'Error: Current versions of WordPress (%1$s) and PHP (%2$s) do not meet minimum requirements for %3$s. The plugin requires WordPress %4$s and PHP %5$s.', 'plugin' ), get_bloginfo( 'version' ), phpversion(), $plugin_headers['Name'], $requirements['requires'], $requirements['requires_php'] ) . $php_update_message . '
' . sprintf( /* translators: 1: Current PHP version, 2: Plugin name, 3: Required PHP version. */ _x( 'Error: Current PHP version (%1$s) does not meet minimum requirements for %2$s. The plugin requires PHP %3$s.', 'plugin' ), phpversion(), $plugin_headers['Name'], $requirements['requires_php'] ) . $php_update_message . '
' . sprintf( /* translators: 1: Current WordPress version, 2: Plugin name, 3: Required WordPress version. */ _x( 'Error: Current WordPress version (%1$s) does not meet minimum requirements for %2$s. The plugin requires WordPress %3$s.', 'plugin' ), get_bloginfo( 'version' ), $plugin_headers['Name'], $requirements['requires'] ) . '