Files
Wallos/endpoints/subscription/exportcalendar.php
Pedro Pombeiro 671763e78b use stable UID for iCal events to prevent duplicates (#966)
Changed UID generation from uniqid() to a stable format based on
subscription ID (wallos-subscription-{id}@wallos). This ensures that
calendar applications update existing events instead of creating
duplicates when the feed is refreshed.

According to RFC 5545 section 3.8.4.7, the UID property must be
globally unique and persistent for the lifetime of the event.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 15:04:41 +00:00

79 lines
2.9 KiB
PHP

<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/validate_endpoint.php';
require_once '../../includes/getdbkeys.php';
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$id = $data['id'];
$stmt = $db->prepare('SELECT * FROM subscriptions WHERE id = :id AND user_id = :userId');
$stmt->bindParam(':id', $id, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $_SESSION['userId'], SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
die(json_encode([
'success' => false,
'message' => "Subscription not found"
]));
}
$subscription = $result->fetchArray(SQLITE3_ASSOC); // Fetch the subscription details as an associative array
if ($subscription) {
$subscription['payer_user'] = $members[$subscription['payer_user_id']]['name'];
$subscription['category'] = $categories[$subscription['category_id']]['name'];
$subscription['payment_method'] = $payment_methods[$subscription['payment_method_id']]['name'];
$subscription['currency'] = $currencies[$subscription['currency_id']]['symbol'];
$subscription['trigger'] = $subscription['notify_days_before'] ? $subscription['notify_days_before'] : 1;
$subscription['price'] = number_format($subscription['price'], 2);
// Create ICS from subscription information
$uid = 'wallos-subscription-' . $subscription['id'] . '@wallos';
$summary = html_entity_decode($subscription['name'], ENT_QUOTES, 'UTF-8');
$description = "Price: {$subscription['currency']}{$subscription['price']}\nCategory: {$subscription['category']}\nPayment Method: {$subscription['payment_method']}\nPayer: {$subscription['payer_user']}\n\nNotes: {$subscription['notes']}";
$dtstamp = gmdate('Ymd\THis\Z');
$dtstart = (new DateTime($subscription['next_payment']))->format('Ymd');
$dtend = (new DateTime($subscription['next_payment']))->format('Ymd');
$location = isset($subscription['url']) ? $subscription['url'] : '';
$alarm_trigger = '-P' . $subscription['trigger'] . 'D';
$icsContent = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Your Organization//Your Application//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
UID:$uid
DTSTAMP:$dtstamp
SUMMARY:$summary
DESCRIPTION:$description
DTSTART;VALUE=DATE:$dtstart
DTEND;VALUE=DATE:$dtend
LOCATION:$location
STATUS:CONFIRMED
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:Reminder
TRIGGER:$alarm_trigger
END:VALARM
END:VEVENT
END:VCALENDAR
ICS;
echo json_encode([
'success' => true,
'ics' => $icsContent,
'name' => $subscription['name']
]);
} else {
echo json_encode([
'success' => false,
'message' => "Subscription not found"
]);
}