Files
GDPR-Content-Blocker/gdpr-content-blocker/includes/class-updater.php
s4luorth ecb5e1bd22 chore: monorepo - plugin, backend und hilfsdaten in einem repo
- Eltern-Ordner ist jetzt EIN Git-Repo (statt getrennter Repos).
- root .gitignore haelt Secrets (.env), node_modules, DB und Build-Artefakte raus.
- release.ps1: manueller Release (ZIP bauen + ans Backend laden).
- root README mit Struktur und Release-Ablauf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:41:38 +02:00

140 lines
4.1 KiB
PHP

<?php
defined( 'ABSPATH' ) || exit;
/**
* Self-hosted update delivery. Asks the license backend whether a newer version
* exists and, if so, injects it into WordPress' update flow. The package is only
* served to licensed, activated sites (the backend gates the download).
*
* Without an active license nothing is offered (CB_License::gate_updates() is the
* additional safety net that strips any stray update entry).
*/
class CB_Updater {
const TRANSIENT = 'cb_update_info';
const CACHE_TTL = 6 * HOUR_IN_SECONDS;
public static function init(): void {
add_filter( 'pre_set_site_transient_update_plugins', [ __CLASS__, 'inject' ] );
add_filter( 'plugins_api', [ __CLASS__, 'plugin_info' ], 20, 3 );
add_action( 'upgrader_process_complete', [ __CLASS__, 'flush_cache' ], 10, 0 );
}
private static function basename(): string {
return plugin_basename( CB_FILE );
}
private static function slug(): string {
return dirname( self::basename() ); // e.g. "gdpr-content-blocker"
}
public static function flush_cache(): void {
delete_transient( self::TRANSIENT );
}
/**
* Fetch update info from the backend (cached). Returns the decoded array
* or null when unlicensed / on error.
*/
private static function fetch_info(): ?array {
if ( ! CB_License::is_active() ) {
return null;
}
$cached = get_transient( self::TRANSIENT );
if ( is_array( $cached ) ) {
return $cached;
}
$lic = CB_License::get_license();
$response = wp_remote_post( CB_License::api_url() . '/api/v1/update', [
'timeout' => 15,
'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ],
'body' => wp_json_encode( [
'key' => $lic['key'],
'product' => CB_PRODUCT_SLUG,
'domain' => CB_License::domain(),
'version' => CB_VERSION,
] ),
] );
if ( is_wp_error( $response ) ) {
return null;
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! is_array( $data ) || empty( $data['ok'] ) ) {
return null;
}
set_transient( self::TRANSIENT, $data, self::CACHE_TTL );
return $data;
}
/** Inject the update into the plugins update transient. */
public static function inject( mixed $transient ): mixed {
if ( ! is_object( $transient ) ) {
return $transient;
}
$info = self::fetch_info();
if ( ! $info || empty( $info['update_available'] ) || empty( $info['package'] ) ) {
return $transient;
}
// Only offer if the backend's version is actually newer than ours.
if ( version_compare( $info['version'] ?? '0', CB_VERSION, '<=' ) ) {
return $transient;
}
$item = [
'slug' => self::slug(),
'plugin' => self::basename(),
'new_version' => (string) $info['version'],
'package' => esc_url_raw( $info['package'] ),
'url' => 'https://lucas-orth.de',
'tested' => (string) ( $info['tested'] ?? '' ),
'requires' => (string) ( $info['requires'] ?? '' ),
'requires_php'=> (string) ( $info['requires_php'] ?? '' ),
'icons' => [],
'banners' => [],
];
$transient->response[ self::basename() ] = (object) $item;
return $transient;
}
/**
* Provide the "View version details" popup content.
*/
public static function plugin_info( mixed $result, string $action, object $args ): mixed {
if ( $action !== 'plugin_information' ) {
return $result;
}
if ( empty( $args->slug ) || $args->slug !== self::slug() ) {
return $result;
}
$info = self::fetch_info();
if ( ! $info ) {
return $result;
}
return (object) [
'name' => 'GDPR Content Blocker',
'slug' => self::slug(),
'version' => (string) ( $info['version'] ?? CB_VERSION ),
'author' => '<a href="https://lucas-orth.de">Lucas Orth</a>',
'homepage' => 'https://lucas-orth.de',
'requires' => (string) ( $info['requires'] ?? '' ),
'tested' => (string) ( $info['tested'] ?? '' ),
'requires_php' => (string) ( $info['requires_php'] ?? '' ),
'download_link' => esc_url_raw( $info['package'] ?? '' ),
'sections' => [
'changelog' => wp_kses_post( $info['changelog'] ?? '' ),
],
];
}
}