This commit is contained in:
Javier Casares 2026-08-24 06:42:23 +00:00
commit c7a8d9efcc
7 changed files with 123 additions and 27 deletions

View file

@ -527,11 +527,16 @@ class Robotstxt_Manager_Installer {
// Free plugins that publish a public download URL in the catalog are
// fetched directly (no auth). Everything else goes through Core's
// authenticated download endpoint (account API key as Bearer).
// authenticated download endpoint (account API key as Bearer), with
// this site's domain for per-domain license binding (Core 1.11.0+).
$use_download_endpoint = ! ( $is_free && '' !== $dl_url );
$zip_url = $use_download_endpoint
? $client->get_store_url() . '/wp-json/robotstxt-core/v1/plugins/' . rawurlencode( $slug ) . '/download'
? add_query_arg(
'domain',
rawurlencode( $this->site_domain() ),
$client->get_store_url() . '/wp-json/robotstxt-core/v1/plugins/' . rawurlencode( $slug ) . '/download'
)
: $dl_url;
$tmp_file = wp_tempnam( $slug . '.zip' );
@ -581,13 +586,25 @@ class Robotstxt_Manager_Installer {
if ( 200 !== $code ) {
wp_delete_file( $tmp_file );
// Surface the store's own error message (e.g. the per-domain
// license "change the domain in your account" explanation).
$body = json_decode( wp_remote_retrieve_body( $response ), true );
$detail = is_array( $body ) && isset( $body['message'] ) && is_string( $body['message'] ) ? $body['message'] : '';
return new WP_Error(
'robotstxt_manager_http',
sprintf(
/* translators: %d: HTTP status code. */
__( 'Download failed (HTTP %d).', 'robotstxt-manager' ),
$code
)
'' !== $detail
? sprintf(
/* translators: 1: HTTP status code, 2: store error message. */
__( 'Download failed (HTTP %1$d): %2$s', 'robotstxt-manager' ),
$code,
$detail
)
: sprintf(
/* translators: %d: HTTP status code. */
__( 'Download failed (HTTP %d).', 'robotstxt-manager' ),
$code
)
);
}
@ -700,6 +717,26 @@ class Robotstxt_Manager_Installer {
*
* @return bool True when the file looks like a valid ZIP archive.
*/
/**
* Returns the normalised domain of the current site.
*
* @return string Domain (e.g. 'example.com').
*/
private function site_domain(): string {
$host = strtolower( (string) wp_parse_url( home_url(), PHP_URL_HOST ) );
// Strip the literal "www." prefix (ltrim would eat any leading w/).
return (string) preg_replace( '/^www\./', '', $host );
}
/**
* Validates a downloaded archive: must exist, be non-empty, and start
* with the ZIP magic bytes "PK".
*
* @param string $file Absolute path to the downloaded file.
*
* @return bool True when the file looks like a ZIP archive.
*/
private function is_valid_zip( string $file ): bool {
if ( ! file_exists( $file ) ) {
return false;