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;
}
};