examples/wordpress-plugin/hightrusted-capture.php
Stefan Schmidt-Egermann 64e9f1144b
feat: initial examples content (v0.1.0)
- Markenrecht-Monitoring (Python) — täglich URLs capturen
- Webhook-Receiver (Node.js Express) — capture.ready Events archivieren
- WordPress-Plugin (PHP) — Captures aus dem WP-Backend
2026-04-25 12:26:09 +02:00

205 lines
8.3 KiB
PHP

<?php
/**
* Plugin Name: hightrusted CAPTURE
* Plugin URI: https://capture.hightrusted.net
* Description: Forensische Web-Captures direkt aus dem WordPress-Backend — mit qualifiziertem Zeitstempel nach RFC 3161 / eIDAS Art. 41.
* Version: 0.1.0
* Requires at least: 6.0
* Requires PHP: 8.1
* Author: hightrusted GmbH
* Author URI: https://hightrusted.net
* License: MIT
* License URI: https://opensource.org/licenses/MIT
* Text Domain: hightrusted-capture
*
* Use-Case:
* Du betreibst ein Forum/Bewertungsportal/Kommentarsystem auf WordPress.
* Bei beleidigenden, rechtswidrigen oder einfach beweisrelevanten Inhalten
* willst du *vor* der Moderation eine forensische Capture haben.
*
* Das Plugin fügt einen Button "Capture erstellen" zur Beitrags-/Kommentar-
* Ansicht hinzu. Klick → Capture entsteht via API → URL + Verify-Link in den
* Beitrags-Metadaten gespeichert.
*/
declare(strict_types=1);
if (!defined('ABSPATH')) {
exit; // Direktaufruf verbieten
}
require_once __DIR__.'/vendor/autoload.php';
use Hightrusted\Capture\Client;
use Hightrusted\Capture\HightrustedException;
class HightrustedCapturePlugin
{
private const OPTION_API_KEY = 'hightrusted_capture_api_key';
public static function init(): void
{
add_action('admin_menu', [self::class, 'addAdminMenu']);
add_action('admin_init', [self::class, 'registerSettings']);
add_action('add_meta_boxes', [self::class, 'addMetaBox']);
add_action('save_post', [self::class, 'handleManualCapture'], 10, 2);
}
// ────────────────────────────────────────────────────────────
// Settings-Page
// ────────────────────────────────────────────────────────────
public static function addAdminMenu(): void
{
add_options_page(
'hightrusted CAPTURE',
'hightrusted CAPTURE',
'manage_options',
'hightrusted-capture',
[self::class, 'renderSettingsPage'],
);
}
public static function registerSettings(): void
{
register_setting('hightrusted_capture', self::OPTION_API_KEY);
}
public static function renderSettingsPage(): void
{
?>
<div class="wrap">
<h1>hightrusted CAPTURE</h1>
<form method="post" action="options.php">
<?php settings_fields('hightrusted_capture'); ?>
<table class="form-table">
<tr>
<th><label for="api_key">API-Key</label></th>
<td>
<input type="password" name="<?= esc_attr(self::OPTION_API_KEY) ?>"
id="api_key" class="regular-text"
value="<?= esc_attr(get_option(self::OPTION_API_KEY, '')) ?>" />
<p class="description">
API-Key holen unter
<a href="https://capture.hightrusted.net/dashboard/api-keys" target="_blank">
capture.hightrusted.net
</a>
</p>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
// ────────────────────────────────────────────────────────────
// Meta-Box im Beitrags-Editor
// ────────────────────────────────────────────────────────────
public static function addMetaBox(): void
{
add_meta_box(
'hightrusted_capture_box',
'hightrusted CAPTURE',
[self::class, 'renderMetaBox'],
['post', 'page'],
'side',
'high',
);
}
public static function renderMetaBox(\WP_Post $post): void
{
wp_nonce_field('hightrusted_capture', 'hightrusted_capture_nonce');
$captureId = get_post_meta($post->ID, '_hightrusted_capture_id', true);
$verifyUrl = get_post_meta($post->ID, '_hightrusted_verify_url', true);
$issuedAt = get_post_meta($post->ID, '_hightrusted_issued_at', true);
if ($captureId) {
?>
<p><strong>✓ Capture vorhanden</strong></p>
<p><code><?= esc_html($captureId) ?></code></p>
<p><a href="<?= esc_url($verifyUrl) ?>" target="_blank">Verifikations-Link</a></p>
<p><em>Zeitstempel: <?= esc_html($issuedAt) ?></em></p>
<p>
<label>
<input type="checkbox" name="hightrusted_recapture" value="1">
Erneut capturen (überschreibt obige)
</label>
</p>
<?php
} else {
?>
<p>Noch keine Capture für diesen Beitrag.</p>
<p>
<label>
<input type="checkbox" name="hightrusted_capture_now" value="1">
Jetzt forensische Capture erstellen
</label>
</p>
<?php
}
}
// ────────────────────────────────────────────────────────────
// Speichern: Capture erstellen wenn angefordert
// ────────────────────────────────────────────────────────────
public static function handleManualCapture(int $postId, \WP_Post $post): void
{
if (!isset($_POST['hightrusted_capture_nonce'])
|| !wp_verify_nonce($_POST['hightrusted_capture_nonce'], 'hightrusted_capture')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!current_user_can('edit_post', $postId)) return;
$shouldCapture = !empty($_POST['hightrusted_capture_now'])
|| !empty($_POST['hightrusted_recapture']);
if (!$shouldCapture) return;
$apiKey = get_option(self::OPTION_API_KEY);
if (!$apiKey) {
self::adminNotice('error', 'hightrusted CAPTURE: API-Key fehlt. Siehe Einstellungen.');
return;
}
try {
$client = new Client(['api_key' => $apiKey]);
$capture = $client->capture([
'url' => get_permalink($postId),
'reference' => "wp-post:{$postId}",
'viewport' => ['width' => 1920, 'height' => 1080],
]);
update_post_meta($postId, '_hightrusted_capture_id', $capture['id']);
update_post_meta($postId, '_hightrusted_verify_url', $capture['verify_url']);
update_post_meta($postId, '_hightrusted_issued_at', $capture['timestamp']['issued_at']);
self::adminNotice('success', sprintf(
'hightrusted CAPTURE erstellt: <a href="%s" target="_blank">Verifikations-Link</a>',
esc_url($capture['verify_url']),
));
} catch (HightrustedException $e) {
self::adminNotice('error', "hightrusted CAPTURE: {$e->getMessage()} (Code: {$e->errorCode})");
}
}
private static function adminNotice(string $type, string $message): void
{
$key = 'hightrusted_capture_notice';
set_transient($key, ['type' => $type, 'message' => $message], 30);
add_action('admin_notices', function () use ($key) {
$notice = get_transient($key);
if (!$notice) return;
delete_transient($key);
printf(
'<div class="notice notice-%s is-dismissible"><p>%s</p></div>',
esc_attr($notice['type']),
wp_kses_post($notice['message']),
);
});
}
}
HightrustedCapturePlugin::init();