$channel] + $data; return $id; } // Relay a staged message to id.andmore.pt and return true on success. The local // `to_user_id` is intentionally NOT forwarded — it's a fotografia id, not a // canonical id.andmore.pt user id (the central queue FK would reject it). The // recipient address + this app's key are enough; the central log records origin. function flush_message(int $id): bool { $data = $GLOBALS['_notify_staged'][$id] ?? null; if (!$data) return false; unset($GLOBALS['_notify_staged'][$id]); $channel = $data['channel'] ?? 'email'; $payload = [ 'channel' => $channel, 'to' => $data['to_address'] ?? '', 'to_name' => $data['to_name'] ?? null, 'body' => $data['body'] ?? '', ]; if ($channel === 'email') { // Preserve the historical subject prefix that the old SMTP path applied. $prefix = defined('EMAIL_SUBJECT_PREFIX') ? EMAIL_SUBJECT_PREFIX : ''; $payload['subject'] = $prefix . ($data['subject'] ?? ''); $payload['alt_body'] = $data['alt_body'] ?? null; } if (!empty($data['context_type'])) { $payload['context'] = ['type' => $data['context_type'], 'id' => $data['context_id'] ?? null]; } if (!empty($data['scheduled_for'])) { $payload['scheduled_for'] = $data['scheduled_for']; } $r = notify_remote_send($payload); return !empty($r['ok']) && (($r['status'] ?? '') !== 'failed'); } // No local queue to drain anymore. Kept as a harmless no-op so any stray caller // (or scheduled task that wasn't updated) doesn't fatal. function process_queue(int $limit = 20): array { return ['sent' => 0, 'failed' => 0, 'total' => 0]; }