wp/wp-admin/includes/plugin-install.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
   172 		);
   172 		);
   173 		$request   = wp_remote_get( $url, $http_args );
   173 		$request   = wp_remote_get( $url, $http_args );
   174 
   174 
   175 		if ( $ssl && is_wp_error( $request ) ) {
   175 		if ( $ssl && is_wp_error( $request ) ) {
   176 			if ( ! wp_is_json_request() ) {
   176 			if ( ! wp_is_json_request() ) {
   177 				trigger_error(
   177 				wp_trigger_error(
       
   178 					__FUNCTION__,
   178 					sprintf(
   179 					sprintf(
   179 						/* translators: %s: Support forums URL. */
   180 						/* translators: %s: Support forums URL. */
   180 						__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   181 						__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   181 						__( 'https://wordpress.org/support/forums/' )
   182 						__( 'https://wordpress.org/support/forums/' )
   182 					) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   183 					) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   314  *
   315  *
   315  * @param bool $deprecated Not used.
   316  * @param bool $deprecated Not used.
   316  */
   317  */
   317 function install_search_form( $deprecated = true ) {
   318 function install_search_form( $deprecated = true ) {
   318 	$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
   319 	$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
   319 	$term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
   320 	$term = isset( $_REQUEST['s'] ) ? urldecode( wp_unslash( $_REQUEST['s'] ) ) : '';
   320 	?>
   321 	?>
   321 	<form class="search-form search-plugins" method="get">
   322 	<form class="search-form search-plugins" method="get">
   322 		<input type="hidden" name="tab" value="search" />
   323 		<input type="hidden" name="tab" value="search" />
   323 		<label class="screen-reader-text" for="typeselector"><?php _e( 'Search plugins by:' ); ?></label>
   324 		<label for="search-plugins"><?php _e( 'Search Plugins' ); ?></label>
       
   325 		<input type="search" name="s" id="search-plugins" value="<?php echo esc_attr( $term ); ?>" class="wp-filter-search" />
       
   326 		<label class="screen-reader-text" for="typeselector">
       
   327 			<?php
       
   328 			/* translators: Hidden accessibility text. */
       
   329 			_e( 'Search plugins by:' );
       
   330 			?>
       
   331 		</label>
   324 		<select name="type" id="typeselector">
   332 		<select name="type" id="typeselector">
   325 			<option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
   333 			<option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
   326 			<option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
   334 			<option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
   327 			<option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option>
   335 			<option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option>
   328 		</select>
   336 		</select>
   329 		<label class="screen-reader-text" for="search-plugins"><?php _e( 'Search Plugins' ); ?></label>
       
   330 		<input type="search" name="s" id="search-plugins" value="<?php echo esc_attr( $term ); ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...' ); ?>" />
       
   331 		<?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?>
   337 		<?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?>
   332 	</form>
   338 	</form>
   333 	<?php
   339 	<?php
   334 }
   340 }
   335 
   341 
   340  */
   346  */
   341 function install_plugins_upload() {
   347 function install_plugins_upload() {
   342 	?>
   348 	?>
   343 <div class="upload-plugin">
   349 <div class="upload-plugin">
   344 	<p class="install-help"><?php _e( 'If you have a plugin in a .zip format, you may install or update it by uploading it here.' ); ?></p>
   350 	<p class="install-help"><?php _e( 'If you have a plugin in a .zip format, you may install or update it by uploading it here.' ); ?></p>
   345 	<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-plugin' ); ?>">
   351 	<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo esc_url( self_admin_url( 'update.php?action=upload-plugin' ) ); ?>">
   346 		<?php wp_nonce_field( 'plugin-upload' ); ?>
   352 		<?php wp_nonce_field( 'plugin-upload' ); ?>
   347 		<label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label>
   353 		<label class="screen-reader-text" for="pluginzip">
       
   354 			<?php
       
   355 			/* translators: Hidden accessibility text. */
       
   356 			_e( 'Plugin zip file' );
       
   357 			?>
       
   358 		</label>
   348 		<input type="file" id="pluginzip" name="pluginzip" accept=".zip" />
   359 		<input type="file" id="pluginzip" name="pluginzip" accept=".zip" />
   349 		<?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?>
   360 		<?php submit_button( _x( 'Install Now', 'plugin' ), '', 'install-plugin-submit', false ); ?>
   350 	</form>
   361 	</form>
   351 </div>
   362 </div>
   352 	<?php
   363 	<?php
   353 }
   364 }
   354 
   365 
   393 			);
   404 			);
   394 			break;
   405 			break;
   395 		case 'install_plugins_featured':
   406 		case 'install_plugins_featured':
   396 			printf(
   407 			printf(
   397 				/* translators: %s: https://wordpress.org/plugins/ */
   408 				/* translators: %s: https://wordpress.org/plugins/ */
   398 				'<p>' . __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="%s">WordPress Plugin Directory</a> or upload a plugin in .zip format by clicking the button at the top of this page.' ) . '</p>',
   409 				'<p>' . __( 'Plugins extend and expand the functionality of WordPress. You may install plugins in the <a href="%s">WordPress Plugin Directory</a> right from here, or upload a plugin in .zip format by clicking the button at the top of this page.' ) . '</p>',
   399 				__( 'https://wordpress.org/plugins/' )
   410 				__( 'https://wordpress.org/plugins/' )
   400 			);
   411 			);
   401 			break;
   412 			break;
   402 		case 'install_plugins_recommended':
   413 		case 'install_plugins_recommended':
   403 			echo '<p>' . __( 'These suggestions are based on the plugins you and other users have installed.' ) . '</p>';
   414 			echo '<p>' . __( 'These suggestions are based on the plugins you and other users have installed.' ) . '</p>';
   469 				if ( current_user_can( 'install_plugins' ) ) {
   480 				if ( current_user_can( 'install_plugins' ) ) {
   470 					$url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug );
   481 					$url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug );
   471 				}
   482 				}
   472 			} else {
   483 			} else {
   473 				$key = array_keys( $installed_plugin );
   484 				$key = array_keys( $installed_plugin );
   474 				// Use the first plugin regardless of the name.
   485 				/*
   475 				// Could have issues for multiple plugins in one directory if they share different version numbers.
   486 				 * Use the first plugin regardless of the name.
       
   487 				 * Could have issues for multiple plugins in one directory if they share different version numbers.
       
   488 				 */
   476 				$key = reset( $key );
   489 				$key = reset( $key );
   477 
   490 
   478 				$update_file = $api->slug . '/' . $key;
   491 				$update_file = $api->slug . '/' . $key;
   479 				if ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '=' ) ) {
   492 				if ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '=' ) ) {
   480 					$status = 'latest_installed';
   493 					$status = 'latest_installed';
   798 	$compatible_php = is_php_version_compatible( $requires_php );
   811 	$compatible_php = is_php_version_compatible( $requires_php );
   799 	$compatible_wp  = is_wp_version_compatible( $requires_wp );
   812 	$compatible_wp  = is_wp_version_compatible( $requires_wp );
   800 	$tested_wp      = ( empty( $api->tested ) || version_compare( get_bloginfo( 'version' ), $api->tested, '<=' ) );
   813 	$tested_wp      = ( empty( $api->tested ) || version_compare( get_bloginfo( 'version' ), $api->tested, '<=' ) );
   801 
   814 
   802 	if ( ! $compatible_php ) {
   815 	if ( ! $compatible_php ) {
   803 		echo '<div class="notice notice-error notice-alt"><p>';
   816 		$compatible_php_notice_message  = '<p>';
   804 		_e( '<strong>Error:</strong> This plugin <strong>requires a newer version of PHP</strong>.' );
   817 		$compatible_php_notice_message .= __( '<strong>Error:</strong> This plugin <strong>requires a newer version of PHP</strong>.' );
       
   818 
   805 		if ( current_user_can( 'update_php' ) ) {
   819 		if ( current_user_can( 'update_php' ) ) {
   806 			printf(
   820 			$compatible_php_notice_message .= sprintf(
   807 				/* translators: %s: URL to Update PHP page. */
   821 				/* translators: %s: URL to Update PHP page. */
   808 				' ' . __( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.' ),
   822 				' ' . __( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.' ),
   809 				esc_url( wp_get_update_php_url() )
   823 				esc_url( wp_get_update_php_url() )
   810 			);
   824 			) . wp_update_php_annotation( '</p><p><em>', '</em>', false );
   811 
       
   812 			wp_update_php_annotation( '</p><p><em>', '</em>' );
       
   813 		} else {
   825 		} else {
   814 			echo '</p>';
   826 			$compatible_php_notice_message .= '</p>';
   815 		}
   827 		}
   816 		echo '</div>';
   828 
       
   829 		wp_admin_notice(
       
   830 			$compatible_php_notice_message,
       
   831 			array(
       
   832 				'type'               => 'error',
       
   833 				'additional_classes' => array( 'notice-alt' ),
       
   834 				'paragraph_wrap'     => false,
       
   835 			)
       
   836 		);
   817 	}
   837 	}
   818 
   838 
   819 	if ( ! $tested_wp ) {
   839 	if ( ! $tested_wp ) {
   820 		echo '<div class="notice notice-warning notice-alt"><p>';
   840 		wp_admin_notice(
   821 		_e( '<strong>Warning:</strong> This plugin <strong>has not been tested</strong> with your current version of WordPress.' );
   841 			__( '<strong>Warning:</strong> This plugin <strong>has not been tested</strong> with your current version of WordPress.' ),
   822 		echo '</p></div>';
   842 			array(
       
   843 				'type'               => 'warning',
       
   844 				'additional_classes' => array( 'notice-alt' ),
       
   845 			)
       
   846 		);
   823 	} elseif ( ! $compatible_wp ) {
   847 	} elseif ( ! $compatible_wp ) {
   824 		echo '<div class="notice notice-error notice-alt"><p>';
   848 		$compatible_wp_notice_message = __( '<strong>Error:</strong> This plugin <strong>requires a newer version of WordPress</strong>.' );
   825 		_e( '<strong>Error:</strong> This plugin <strong>requires a newer version of WordPress</strong>.' );
       
   826 		if ( current_user_can( 'update_core' ) ) {
   849 		if ( current_user_can( 'update_core' ) ) {
   827 			printf(
   850 			$compatible_wp_notice_message .= sprintf(
   828 				/* translators: %s: URL to WordPress Updates screen. */
   851 				/* translators: %s: URL to WordPress Updates screen. */
   829 				' ' . __( '<a href="%s" target="_parent">Click here to update WordPress</a>.' ),
   852 				' ' . __( '<a href="%s" target="_parent">Click here to update WordPress</a>.' ),
   830 				self_admin_url( 'update-core.php' )
   853 				esc_url( self_admin_url( 'update-core.php' ) )
   831 			);
   854 			);
   832 		}
   855 		}
   833 		echo '</p></div>';
   856 
       
   857 		wp_admin_notice(
       
   858 			$compatible_wp_notice_message,
       
   859 			array(
       
   860 				'type'               => 'error',
       
   861 				'additional_classes' => array( 'notice-alt' ),
       
   862 			)
       
   863 		);
   834 	}
   864 	}
   835 
   865 
   836 	foreach ( (array) $api->sections as $section_name => $content ) {
   866 	foreach ( (array) $api->sections as $section_name => $content ) {
   837 		$content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' );
   867 		$content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' );
   838 		$content = links_add_target( $content, '_blank' );
   868 		$content = links_add_target( $content, '_blank' );
   848 	echo "</div>\n";
   878 	echo "</div>\n";
   849 	echo "</div>\n";
   879 	echo "</div>\n";
   850 	echo "</div>\n"; // #plugin-information-scrollable
   880 	echo "</div>\n"; // #plugin-information-scrollable
   851 	echo "<div id='$tab-footer'>\n";
   881 	echo "<div id='$tab-footer'>\n";
   852 	if ( ! empty( $api->download_link ) && ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) ) {
   882 	if ( ! empty( $api->download_link ) && ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) ) {
   853 		$status = install_plugin_install_status( $api );
   883 		$button = wp_get_plugin_action_button( $api->name, $api, $compatible_php, $compatible_wp );
       
   884 		$button = str_replace( 'class="', 'class="right ', $button );
       
   885 
       
   886 		if ( ! str_contains( $button, _x( 'Activate', 'plugin' ) ) ) {
       
   887 			$button = str_replace( 'class="', 'id="plugin_install_from_iframe" class="', $button );
       
   888 		}
       
   889 
       
   890 		echo wp_kses_post( $button );
       
   891 	}
       
   892 	echo "</div>\n";
       
   893 
       
   894 	wp_print_request_filesystem_credentials_modal();
       
   895 	wp_print_admin_notice_templates();
       
   896 
       
   897 	iframe_footer();
       
   898 	exit;
       
   899 }
       
   900 
       
   901 /**
       
   902  * Gets the markup for the plugin install action button.
       
   903  *
       
   904  * @since 6.5.0
       
   905  *
       
   906  * @param string       $name           Plugin name.
       
   907  * @param array|object $data           {
       
   908  *     An array or object of plugin data. Can be retrieved from the API.
       
   909  *
       
   910  *     @type string   $slug             The plugin slug.
       
   911  *     @type string[] $requires_plugins An array of plugin dependency slugs.
       
   912  *     @type string   $version          The plugin's version string. Used when getting the install status.
       
   913  * }
       
   914  * @param bool         $compatible_php   The result of a PHP compatibility check.
       
   915  * @param bool         $compatible_wp    The result of a WP compatibility check.
       
   916  * @return string The markup for the dependency row button. An empty string if the user does not have capabilities.
       
   917  */
       
   918 function wp_get_plugin_action_button( $name, $data, $compatible_php, $compatible_wp ) {
       
   919 	$button           = '';
       
   920 	$data             = (object) $data;
       
   921 	$status           = install_plugin_install_status( $data );
       
   922 	$requires_plugins = $data->requires_plugins ?? array();
       
   923 
       
   924 	// Determine the status of plugin dependencies.
       
   925 	$installed_plugins                   = get_plugins();
       
   926 	$active_plugins                      = get_option( 'active_plugins', array() );
       
   927 	$plugin_dependencies_count           = count( $requires_plugins );
       
   928 	$installed_plugin_dependencies_count = 0;
       
   929 	$active_plugin_dependencies_count    = 0;
       
   930 	foreach ( $requires_plugins as $dependency ) {
       
   931 		foreach ( array_keys( $installed_plugins ) as $installed_plugin_file ) {
       
   932 			if ( str_contains( $installed_plugin_file, '/' ) && explode( '/', $installed_plugin_file )[0] === $dependency ) {
       
   933 				++$installed_plugin_dependencies_count;
       
   934 			}
       
   935 		}
       
   936 
       
   937 		foreach ( $active_plugins as $active_plugin_file ) {
       
   938 			if ( str_contains( $active_plugin_file, '/' ) && explode( '/', $active_plugin_file )[0] === $dependency ) {
       
   939 				++$active_plugin_dependencies_count;
       
   940 			}
       
   941 		}
       
   942 	}
       
   943 	$all_plugin_dependencies_installed = $installed_plugin_dependencies_count === $plugin_dependencies_count;
       
   944 	$all_plugin_dependencies_active    = $active_plugin_dependencies_count === $plugin_dependencies_count;
       
   945 
       
   946 	if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) {
   854 		switch ( $status['status'] ) {
   947 		switch ( $status['status'] ) {
   855 			case 'install':
   948 			case 'install':
   856 				if ( $status['url'] ) {
   949 				if ( $status['url'] ) {
   857 					if ( $compatible_php && $compatible_wp ) {
   950 					if ( $compatible_php && $compatible_wp && $all_plugin_dependencies_installed && ! empty( $data->download_link ) ) {
   858 						echo '<a data-slug="' . esc_attr( $api->slug ) . '" id="plugin_install_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Now' ) . '</a>';
   951 						$button = sprintf(
       
   952 							'<a class="install-now button" data-slug="%s" href="%s" aria-label="%s" data-name="%s" role="button">%s</a>',
       
   953 							esc_attr( $data->slug ),
       
   954 							esc_url( $status['url'] ),
       
   955 							/* translators: %s: Plugin name and version. */
       
   956 							esc_attr( sprintf( _x( 'Install %s now', 'plugin' ), $name ) ),
       
   957 							esc_attr( $name ),
       
   958 							_x( 'Install Now', 'plugin' )
       
   959 						);
   859 					} else {
   960 					} else {
   860 						printf(
   961 						$button = sprintf(
   861 							'<button type="button" class="button button-primary button-disabled right" disabled="disabled">%s</button>',
   962 							'<button type="button" class="install-now button button-disabled" disabled="disabled">%s</button>',
   862 							_x( 'Cannot Install', 'plugin' )
   963 							_x( 'Install Now', 'plugin' )
   863 						);
   964 						);
   864 					}
   965 					}
   865 				}
   966 				}
   866 				break;
   967 				break;
       
   968 
   867 			case 'update_available':
   969 			case 'update_available':
   868 				if ( $status['url'] ) {
   970 				if ( $status['url'] ) {
   869 					if ( $compatible_php ) {
   971 					if ( $compatible_php && $compatible_wp ) {
   870 						echo '<a data-slug="' . esc_attr( $api->slug ) . '" data-plugin="' . esc_attr( $status['file'] ) . '" id="plugin_update_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Update Now' ) . '</a>';
   972 						$button = sprintf(
       
   973 							'<a class="update-now button aria-button-if-js" data-plugin="%s" data-slug="%s" href="%s" aria-label="%s" data-name="%s" role="button">%s</a>',
       
   974 							esc_attr( $status['file'] ),
       
   975 							esc_attr( $data->slug ),
       
   976 							esc_url( $status['url'] ),
       
   977 							/* translators: %s: Plugin name and version. */
       
   978 							esc_attr( sprintf( _x( 'Update %s now', 'plugin' ), $name ) ),
       
   979 							esc_attr( $name ),
       
   980 							_x( 'Update Now', 'plugin' )
       
   981 						);
   871 					} else {
   982 					} else {
   872 						printf(
   983 						$button = sprintf(
   873 							'<button type="button" class="button button-primary button-disabled right" disabled="disabled">%s</button>',
   984 							'<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
   874 							_x( 'Cannot Update', 'plugin' )
   985 							_x( 'Update Now', 'plugin' )
   875 						);
   986 						);
   876 					}
   987 					}
   877 				}
   988 				}
   878 				break;
   989 				break;
       
   990 
       
   991 			case 'latest_installed':
   879 			case 'newer_installed':
   992 			case 'newer_installed':
   880 				/* translators: %s: Plugin version. */
   993 				if ( is_plugin_active( $status['file'] ) ) {
   881 				echo '<a class="button button-primary right disabled">' . sprintf( __( 'Newer Version (%s) Installed' ), esc_html( $status['version'] ) ) . '</a>';
   994 					$button = sprintf(
       
   995 						'<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
       
   996 						_x( 'Active', 'plugin' )
       
   997 					);
       
   998 				} elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) {
       
   999 					if ( $compatible_php && $compatible_wp && $all_plugin_dependencies_active ) {
       
  1000 						$button_text = _x( 'Activate', 'plugin' );
       
  1001 						/* translators: %s: Plugin name. */
       
  1002 						$button_label = _x( 'Activate %s', 'plugin' );
       
  1003 						$activate_url = add_query_arg(
       
  1004 							array(
       
  1005 								'_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ),
       
  1006 								'action'   => 'activate',
       
  1007 								'plugin'   => $status['file'],
       
  1008 							),
       
  1009 							network_admin_url( 'plugins.php' )
       
  1010 						);
       
  1011 
       
  1012 						if ( is_network_admin() ) {
       
  1013 							$button_text = _x( 'Network Activate', 'plugin' );
       
  1014 							/* translators: %s: Plugin name. */
       
  1015 							$button_label = _x( 'Network Activate %s', 'plugin' );
       
  1016 							$activate_url = add_query_arg( array( 'networkwide' => 1 ), $activate_url );
       
  1017 						}
       
  1018 
       
  1019 						$button = sprintf(
       
  1020 							'<a href="%1$s" data-name="%2$s" data-slug="%3$s" data-plugin="%4$s" class="button button-primary activate-now" aria-label="%5$s" role="button">%6$s</a>',
       
  1021 							esc_url( $activate_url ),
       
  1022 							esc_attr( $name ),
       
  1023 							esc_attr( $data->slug ),
       
  1024 							esc_attr( $status['file'] ),
       
  1025 							esc_attr( sprintf( $button_label, $name ) ),
       
  1026 							$button_text
       
  1027 						);
       
  1028 					} else {
       
  1029 						$button = sprintf(
       
  1030 							'<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
       
  1031 							is_network_admin() ? _x( 'Network Activate', 'plugin' ) : _x( 'Activate', 'plugin' )
       
  1032 						);
       
  1033 					}
       
  1034 				} else {
       
  1035 					$button = sprintf(
       
  1036 						'<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
       
  1037 						_x( 'Installed', 'plugin' )
       
  1038 					);
       
  1039 				}
   882 				break;
  1040 				break;
   883 			case 'latest_installed':
  1041 		}
   884 				echo '<a class="button button-primary right disabled">' . __( 'Latest Version Installed' ) . '</a>';
  1042 	}
   885 				break;
  1043 
   886 		}
  1044 	return $button;
   887 	}
       
   888 	echo "</div>\n";
       
   889 
       
   890 	iframe_footer();
       
   891 	exit;
       
   892 }
  1045 }