Skip to content

Instantly share code, notes, and snippets.

@Rarst
Last active May 13, 2019 02:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Rarst/d75dbd6d9c77e5f33940d1e5abc931d0 to your computer and use it in GitHub Desktop.
Save Rarst/d75dbd6d9c77e5f33940d1e5abc931d0 to your computer and use it in GitHub Desktop.
Quick and dirty WP endpoint to redirect to a download of attached file for a latest GitHub release.
<?php
declare( strict_types=1 );
new class( 'Rarst', [ 'laps' ] ) {
private $owner, $repos;
private $endpoint = 'download';
public function __construct( string $owner, array $repos ) {
$this->owner = $owner;
$this->repos = $repos;
add_action( 'init', [ $this, 'init' ] );
}
public function init() {
add_rewrite_endpoint( $this->endpoint, EP_ROOT );
add_filter( 'posts_where', [ $this, 'posts_where' ], 10, 2 );
add_filter( 'template_include', [ $this, 'template_include' ], 9 );
}
public function posts_where( $where, $query ) {
if ( isset( $query->query[ $this->endpoint ] ) ) {
return ' AND 1=0';
}
return $where;
}
public function template_include( $template ) {
global $wp_query;
$repo_name = $wp_query->query[ $this->endpoint ] ?? '';
if ( ! in_array( $repo_name, $this->repos, true ) ) {
return $template;
}
$transient_key = "latest-release-{$this->owner}/{$repo_name}";
$api_url = "https://api.github.com/repos/{$this->owner}/{$repo_name}/releases/latest";
$release_url = "https://github.com/{$this->owner}/{$repo_name}/releases/latest";
$response = get_transient( $transient_key );
if ( empty( $response ) ) {
$response = wp_remote_get( $api_url );
$response = wp_remote_retrieve_body( $response );
if ( empty( $response ) ) {
wp_redirect( $release_url );
die;
}
set_transient( $transient_key, $response, 15 * MINUTE_IN_SECONDS );
}
$response = json_decode( $response );
$redirect_url = $response->assets[0]->browser_download_url ?? $release_url;
wp_redirect( $redirect_url );
die;
}
};
@afragen
Copy link

afragen commented Nov 10, 2018

I recently found an action hook that will show the $download_url. This is how I use it in GitHub Updater.

https://github.com/afragen/github-updater/blob/1a05595b0ed0dcb0a8c625b5c42162853fe42fcc/src/GitHub_Updater/API.php#L786

@Rarst
Copy link
Author

Rarst commented Nov 11, 2018

I don't quite follow the difference about what you are doing and how AWS is involved.

What my code is doing:

  1. Making an API request to /repos/:owner/:repo/releases/latest e.g. https://api.github.com/repos/rarst/laps/releases/latest
  2. Looking up first asset in it (I only have one usually) and browser_download_url in it, e.g. https://github.com/Rarst/laps/releases/download/2.0/laps-2.0.zip, which is where I want to send client.

Could you please elaborate what do you think could be simplified here?

@afragen
Copy link

afragen commented Nov 11, 2018

The URL that leads to for the zipfile is https://github-production-release-asset-2e65be.s3.amazonaws.com/19918104/36284318-1ae2-11e8-8cab-c6bf9500cf02?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20181111%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20181111T060155Z&X-Amz-Expires=300&X-Amz-Signature=1801293b227f02238cab73c5c839c473f33d48855e963fc85e290246c9e50644&X-Amz-SignedHeaders=host&actor_id=1296790&response-content-disposition=attachment%3B%20filename%3Dlaps-2.0.zip&response-content-type=application%2Foctet-stream

I was using that for updating from release assets but because of the X-Amz-Expires=300 I can only store it for 5 minutes(300 seconds).

If you only need to send a client the release asset URL and have them download from the browser you’re OK. I was downloading the zipfile in WP core for updating and needed the AWS link.

My mistake in thinking we were doing the same thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment