Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

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

This comment has been minimized.

Owner

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

This comment has been minimized.

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