philippurbschat.de/dinos/google_helper.php

150 lines
No EOL
6 KiB
PHP

<?php
/*
* 2026-01-08 16:45:00 - Dino Karl
* GOOGLE HELPER KLASSE V2 (Mit Upload & Album Logic)
*/
class GoogleHelper {
private $clientId;
private $clientSecret;
private $redirectUri;
private $tokenFile = 'tokens.json';
private $albumFile = 'album_id.txt'; // Hier merken wir uns die Album ID
public function __construct($secretJsonPath, $redirectUri) {
if (!file_exists($secretJsonPath)) die("Fehler: client_secret.json fehlt!");
$secrets = json_decode(file_get_contents($secretJsonPath), true);
$conf = isset($secrets['web']) ? $secrets['web'] : (isset($secrets['installed']) ? $secrets['installed'] : null);
$this->clientId = $conf['client_id'];
$this->clientSecret = $conf['client_secret'];
$this->redirectUri = $redirectUri;
}
// --- AUTH LOGIK (Unverändert) ---
public function getAuthUrl() {
$params = [
'client_id' => $this->clientId, 'redirect_uri' => $this->redirectUri, 'response_type' => 'code',
'scope' => 'https://www.googleapis.com/auth/photoslibrary.appendonly',
'access_type' => 'offline', 'prompt' => 'consent'
];
return 'https://accounts.google.com/o/oauth2/auth?' . http_build_query($params);
}
public function authenticate($code) {
$data = $this->makeRequest('https://oauth2.googleapis.com/token', [
'code' => $code, 'client_id' => $this->clientId, 'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectUri, 'grant_type' => 'authorization_code'
]);
if (isset($data['access_token'])) { $this->saveTokens($data); return true; }
return false;
}
private function getAccessToken() {
$tokens = $this->loadTokens();
if (!$tokens) return null;
if (time() >= ($tokens['created'] + $tokens['expires_in'] - 60)) {
return $this->refreshToken($tokens['refresh_token']);
}
return $tokens['access_token'];
}
private function refreshToken($refresh) {
$data = $this->makeRequest('https://oauth2.googleapis.com/token', [
'refresh_token' => $refresh, 'client_id' => $this->clientId,
'client_secret' => $this->clientSecret, 'grant_type' => 'refresh_token'
]);
if (isset($data['access_token'])) {
$data['refresh_token'] = $refresh; // Alten Refresh Token behalten
$this->saveTokens($data);
return $data['access_token'];
}
return null;
}
// --- NEU: UPLOAD LOGIK ---
public function uploadImage($imageData, $description) {
$token = $this->getAccessToken();
if (!$token) return ['error' => 'Nicht eingeloggt'];
// 1. Das Album finden oder erstellen
$albumId = $this->getOrCreateAlbum($token);
// 2. Die Bytes hochladen (Schritt 1 von 2 bei Google)
$uploadUrl = 'https://photoslibrary.googleapis.com/v1/uploads';
$ch = curl_init($uploadUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token",
"Content-type: application/octet-stream",
"X-Goog-Upload-Protocol: raw"
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $imageData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$uploadToken = curl_exec($ch);
curl_close($ch);
if (!$uploadToken) return ['error' => 'Upload der Bilddaten fehlgeschlagen'];
// 3. Das MediaItem erstellen (Schritt 2 von 2)
$createUrl = 'https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate';
$body = [
"albumId" => $albumId,
"newMediaItems" => [[
"description" => $description,
"simpleMediaItem" => ["uploadToken" => $uploadToken]
]]
];
$ch = curl_init($createUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $token", "Content-type: application/json"]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
return $result;
}
// Hilfsfunktion: Album Management
private function getOrCreateAlbum($token) {
// Haben wir die ID schon gespeichert?
if (file_exists($this->albumFile)) {
return trim(file_get_contents($this->albumFile));
}
// Nein, wir erstellen es neu.
// (Hinweis: Wir könnten erst suchen, aber Erstellen ist sicherer/einfacher)
$url = 'https://photoslibrary.googleapis.com/v1/albums';
$body = json_encode(["album" => ["title" => "Dino Wissenskarten"]]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $token", "Content-type: application/json"]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (isset($response['id'])) {
file_put_contents($this->albumFile, $response['id']);
return $response['id'];
}
return null;
}
// --- UTIL ---
private function makeRequest($url, $fields) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch); curl_close($ch);
return json_decode($res, true);
}
private function saveTokens($data) { $data['created'] = time(); file_put_contents($this->tokenFile, json_encode($data)); }
private function loadTokens() { return file_exists($this->tokenFile) ? json_decode(file_get_contents($this->tokenFile), true) : null; }
public function isAuthenticated() { return file_exists($this->tokenFile); }
}
?>