<?php
add_filter( 'http_request_args', function( $r, $url ) {
	// If this isn't an update request, bail immediately.
	// Regex source: https://github.com/cftp/external-update-api/blob/master/external-update-api/euapi.php#L45
	if ( false === strpos( $url, 'api.wordpress.org' ) || ! preg_match( '#://api\.wordpress\.org/(?P<type>plugins|themes)/update-check/(?P<version>[0-9.]+)/#', $url, $matches ) ) {
		return $r;
	}

	$api_type = $matches['type'];
	$api_version = floatval( $matches['version'] );

	$entities = $r['body'][ $api_type ];
	$entities = ( 1.0 == $api_version ) ? unserialize( $entities ) : json_decode( $entities, true );

	if ( 'plugins' == $api_type ) {
		$entities = (array) $entities;

		foreach ( $entities['plugins'] as $plugin_file => $plugin ) {
			$path = trailingslashit( WP_PLUGIN_DIR . '/' . dirname( $plugin_file ) );
			if ( ! ( file_exists( $path . 'composer.json' ) || is_dir( $path . '.git' ) ) ) {
				continue;
			}

			unset( $entities['plugins'][ $plugin_file ] );
			unset( $entities['plugins']['active'][ array_search( $plugin_file, $entities['active'] ) ] );
		}

		// Cast back to an object.
		if ( 1.0 == $api_version ) {
			$entities = (object) $entities;
		}
	} elseif ( 'themes' == $api_type ) {
		foreach ( $entities['themes'] as $theme_slug => $theme_data ) {
			$path = trailingslashit( wp_get_theme( $theme_slug )->get_stylesheet_directory() );
			if ( ! ( file_exists( $path . 'composer.json' ) || is_dir( $path . '.git' ) ) ) {
				continue;
			}

			unset( $entities['themes'][ $theme_slug ] );
		}
	}

	$r['body'][ $api_type ] = ( 1.0 == $api_version ) ? serialize( $entities ) : json_encode( $entities );

	return $r;
}, 10, 2 );