@@ -271,6 +271,8 @@ protected function get_all_items() {
271271 'file ' => $ file ,
272272 'auto_update ' => false ,
273273 'tested_up_to ' => '' ,
274+ 'requires ' => '' ,
275+ 'requires_php ' => '' ,
274276 'wporg_status ' => $ wporg_info ['status ' ],
275277 'wporg_last_updated ' => $ wporg_info ['last_updated ' ],
276278 );
@@ -293,6 +295,8 @@ protected function get_all_items() {
293295 'auto_update ' => false ,
294296 'author ' => $ item_data ['Author ' ],
295297 'tested_up_to ' => '' ,
298+ 'requires ' => '' ,
299+ 'requires_php ' => '' ,
296300 'wporg_status ' => '' ,
297301 'wporg_last_updated ' => '' ,
298302 ];
@@ -740,6 +744,8 @@ public function update( $args, $assoc_args ) {
740744 }
741745
742746 protected function get_item_list () {
747+ global $ wp_version ;
748+
743749 $ items = [];
744750 $ duplicate_names = [];
745751
@@ -760,29 +766,62 @@ protected function get_item_list() {
760766 $ update_info = ( isset ( $ all_update_info ->response [ $ file ] ) && null !== $ all_update_info ->response [ $ file ] ) ? (array ) $ all_update_info ->response [ $ file ] : null ;
761767 $ name = Utils \get_plugin_name ( $ file );
762768 $ wporg_info = $ this ->get_wporg_data ( $ name );
769+ $ plugin_data = get_plugin_data ( WP_PLUGIN_DIR . '/ ' . $ file , false , false );
763770
764771 if ( ! isset ( $ duplicate_names [ $ name ] ) ) {
765772 $ duplicate_names [ $ name ] = array ();
766773 }
767774
775+ $ php_version = PHP_VERSION ;
776+
777+ $ requires = isset ( $ update_info ) && isset ( $ update_info ['requires ' ] ) ? $ update_info ['requires ' ] : null ;
778+ $ requires_php = isset ( $ update_info ) && isset ( $ update_info ['requires_php ' ] ) ? $ update_info ['requires_php ' ] : null ;
779+
780+ // If an update has requires_php set, check to see if the local version of PHP meets that requirement
781+ // The plugins update API already filters out plugins that don't meet WordPress requirements, but does not
782+ // filter out plugins based on PHP requirements -- so we must do that here
783+ $ compatible_php = empty ( $ requires_php ) || version_compare ( PHP_VERSION , $ requires_php , '>= ' );
784+
785+ if ( ! $ compatible_php ) {
786+ $ update = 'unavailable ' ;
787+ $ update_unavailable_reason = "Requires a newer version of PHP [ $ requires_php] than available [ $ php_version] " ;
788+ } else {
789+ $ update = $ update_info ? 'available ' : 'none ' ;
790+ }
791+
792+ // requires and requires_php are only provided by the plugins update API in the case of an update available.
793+ // For display consistency, get these values from the current plugin file if they aren't in this response
794+ if ( null === $ requires ) {
795+ $ requires = ! empty ( $ plugin_data ['RequiresWP ' ] ) ? $ plugin_data ['RequiresWP ' ] : '' ;
796+ }
797+
798+ if ( null === $ requires_php ) {
799+ $ requires_php = ! empty ( $ plugin_data ['RequiresPHP ' ] ) ? $ plugin_data ['RequiresPHP ' ] : '' ;
800+ }
801+
768802 $ duplicate_names [ $ name ][] = $ file ;
769803 $ items [ $ file ] = [
770- 'name ' => $ name ,
771- 'status ' => $ this ->get_status ( $ file ),
772- 'update ' => (bool ) $ update_info ,
773- 'update_version ' => isset ( $ update_info ) && isset ( $ update_info ['new_version ' ] ) ? $ update_info ['new_version ' ] : null ,
774- 'update_package ' => isset ( $ update_info ) && isset ( $ update_info ['package ' ] ) ? $ update_info ['package ' ] : null ,
775- 'version ' => $ details ['Version ' ],
776- 'update_id ' => $ file ,
777- 'title ' => $ details ['Name ' ],
778- 'description ' => wordwrap ( $ details ['Description ' ] ),
779- 'file ' => $ file ,
780- 'auto_update ' => in_array ( $ file , $ auto_updates , true ),
781- 'author ' => $ details ['Author ' ],
782- 'tested_up_to ' => '' ,
783- 'wporg_status ' => $ wporg_info ['status ' ],
784- 'wporg_last_updated ' => $ wporg_info ['last_updated ' ],
785- 'recently_active ' => in_array ( $ file , array_keys ( $ recently_active ), true ),
804+ 'name ' => $ name ,
805+ 'status ' => $ this ->get_status ( $ file ),
806+ 'update ' => $ update ,
807+ 'update_version ' => isset ( $ update_info ) && isset ( $ update_info ['new_version ' ] ) ? $ update_info ['new_version ' ] : null ,
808+ 'update_package ' => isset ( $ update_info ) && isset ( $ update_info ['package ' ] ) ? $ update_info ['package ' ] : null ,
809+ 'version ' => $ details ['Version ' ],
810+ 'update_id ' => $ file ,
811+ 'title ' => $ details ['Name ' ],
812+ 'description ' => wordwrap ( $ details ['Description ' ] ),
813+ 'file ' => $ file ,
814+ 'auto_update ' => in_array ( $ file , $ auto_updates , true ),
815+ 'author ' => $ details ['Author ' ],
816+ 'tested_up_to ' => '' ,
817+ 'requires ' => $ requires ,
818+ 'requires_php ' => $ requires_php ,
819+ 'wporg_status ' => $ wporg_info ['status ' ],
820+ 'wporg_last_updated ' => $ wporg_info ['last_updated ' ],
821+
822+ 'recently_active ' => in_array ( $ file , array_keys ( $ recently_active ), true ),
823+
824+ 'update_unavailable_reason ' => isset ( $ update_unavailable_reason ) ? $ update_unavailable_reason : '' ,
786825 ];
787826
788827 if ( $ this ->check_headers ['tested_up_to ' ] ) {
@@ -817,9 +856,25 @@ protected function get_item_list() {
817856 // Get info for all plugins that don't have an update.
818857 $ plugin_update_info = isset ( $ all_update_info ->no_update [ $ file ] ) ? $ all_update_info ->no_update [ $ file ] : null ;
819858
820- // Compare version and update information in plugin list .
859+ // Check if local version is newer than what is listed upstream .
821860 if ( null !== $ plugin_update_info && version_compare ( $ details ['Version ' ], $ plugin_update_info ->new_version , '> ' ) ) {
822- $ items [ $ file ]['update ' ] = static ::INVALID_VERSION_MESSAGE ;
861+ $ items [ $ file ]['update ' ] = static ::INVALID_VERSION_MESSAGE ;
862+ $ items [ $ file ]['requires ' ] = isset ( $ plugin_update_info ->requires ) ? $ plugin_update_info ->requires : null ;
863+ $ items [ $ file ]['requires_php ' ] = isset ( $ plugin_update_info ->requires_php ) ? $ plugin_update_info ->requires_php : null ;
864+ }
865+
866+ // If there is a plugin in no_update with a newer version than the local copy, it is because the plugins update api
867+ // has already filtered it because the local WordPress version is too low
868+ if ( null !== $ plugin_update_info && version_compare ( $ details ['Version ' ], $ plugin_update_info ->new_version , '< ' ) ) {
869+ $ items [ $ file ]['update ' ] = 'unavailable ' ;
870+ $ items [ $ file ]['update_version ' ] = $ plugin_update_info ->new_version ;
871+ $ items [ $ file ]['requires ' ] = isset ( $ plugin_update_info ->requires ) ? $ plugin_update_info ->requires : null ;
872+ $ items [ $ file ]['requires_php ' ] = isset ( $ plugin_update_info ->requires_php ) ? $ plugin_update_info ->requires_php : null ;
873+
874+ $ reason = "Requires a newer version of WordPress [ $ plugin_update_info ->requires ] than installed [ $ wp_version] " ;
875+
876+ $ items [ $ file ]['update_unavailable_reason ' ] = $ reason ;
877+
823878 }
824879 }
825880 }
@@ -1397,6 +1452,8 @@ public function delete( $args, $assoc_args = array() ) {
13971452 * * file
13981453 * * author
13991454 * * tested_up_to
1455+ * * requires
1456+ * * requires_php
14001457 * * wporg_status
14011458 * * wporg_last_updated
14021459 *
@@ -1488,7 +1545,6 @@ protected function get_status( $file ) {
14881545 if ( is_plugin_active_for_network ( $ file ) ) {
14891546 return 'active-network ' ;
14901547 }
1491-
14921548 if ( is_plugin_active ( $ file ) ) {
14931549 return 'active ' ;
14941550 }
0 commit comments