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 |
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 } |