*/ public function via(object $notifiable): array { return ['mail']; } public function toMail(object $notifiable): MailMessage { $url = 'https://'.$this->instance->subdomain.'.'.config('provisioning.dns.zone'); [$from, $replyTo] = $this->mailboxAddresses(MailPurpose::PROVISIONING); $message = (new MailMessage)->mailer('cp_'.MailPurpose::PROVISIONING); if ($from !== null) { $message->from($from->address, $from->name); } if ($replyTo !== null) { $message->replyTo($replyTo->address, $replyTo->name); } // ->view() rather than the notification's markdown builder: the default // arrives with the framework's logo, button and footer, and this is the // mail that greets somebody on the day their product starts working. // Kept as a Notification rather than turned into a Mailable, because // CompleteProvisioning depends on it being sent synchronously and on // what happens after the send returns. return $message ->subject(__('provisioning.mail.ready_subject')) ->view('mail.cloud-ready', [ 'name' => (string) ($notifiable->name ?? ''), 'url' => $url, 'plan' => $this->instance->plan, 'storage' => __('provisioning.mail.value_storage', ['gb' => $this->instance->quota_gb]), 'location' => $this->location(), 'dashboardUrl' => route('dashboard'), ]); } /** * The datacenter in words, falling back to the code. * * Read through the host, because an instance knows which machine it is on * and a machine knows where it stands. A missing name is not worth a second * query or an empty row — the code is what the customer chose at checkout * and will recognise. */ private function location(): string { $code = $this->instance->host?->datacenter; if (! is_string($code) || $code === '') { return '—'; } $datacenter = \App\Models\Datacenter::query()->where('code', $code)->first(); if ($datacenter === null) { return $code; } return $datacenter->facility ? $datacenter->name.' · '.$datacenter->facility : $datacenter->name; } }