['DOLAPIKEY: ' . DOLIBARR_API_KEY, 'Accept: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, ]); $body = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return ['status' => $status, 'data' => json_decode($body, true)]; } function doli_update_member(string $member_id, array $fields): void { $url = DOLIBARR_URL . '/api/index.php/members/' . $member_id; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'PUT', CURLOPT_POSTFIELDS => json_encode($fields), CURLOPT_HTTPHEADER => ['DOLAPIKEY: ' . DOLIBARR_API_KEY, 'Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, ]); curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($status !== 200) throw new RuntimeException("Dolibarr update échoué ($status)"); } function doli_add_subscription(string $member_id, int $date_fin_actuel, int $amount): void { $now = time(); $start = ($date_fin_actuel > $now) ? $date_fin_actuel : $now; $end = strtotime('+1 year', $start); $resp = _doli_post("members/$member_id/subscriptions", [ 'start_date' => $start, 'end_date' => $end, 'amount' => $amount, 'label' => 'Adhésion annuelle (HelloAsso)', ]); if ($resp['status'] !== 200 && $resp['status'] !== 201) { throw new RuntimeException("Dolibarr subscription échouée ({$resp['status']}): {$resp['body']}"); } } function _doli_post(string $path, array $data): array { $url = DOLIBARR_URL . '/api/index.php/' . ltrim($path, '/'); $body = json_encode($data); $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => ['DOLAPIKEY: ' . DOLIBARR_API_KEY, 'Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, ]); $resp = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return ['status' => $status, 'body' => $resp]; } function doli_get_membership(string $email): ?array { $resp = _doli_get('members', ['sqlfilters' => "(t.email:=:'$email')"]); if ($resp['status'] !== 200 || empty($resp['data'])) return null; $m = $resp['data'][0]; $date_fin = $m['datefin'] ?? null; return [ 'id' => $m['id'] ?? null, 'firstname' => $m['firstname'] ?? '', 'lastname' => $m['lastname'] ?? '', 'email' => $m['email'] ?? '', 'status' => (int)($m['status'] ?? 0), 'date_fin' => $date_fin ? date('d/m/Y', (int)$date_fin) : null, 'date_fin_ts' => $date_fin ? (int)$date_fin : 0, 'type_label' => $m['type'] ?? '', 'address' => $m['address'] ?? null, 'zip' => $m['zip'] ?? null, 'town' => $m['town'] ?? null, 'country_code' => $m['country_code'] ?? 'FR', ]; }