['on' => !empty($stored['email']['on']), 'to' => (string) ($stored['email']['to'] ?? get_site_option('admin_email', ''))], 'webhook' => ['on' => !empty($stored['webhook']['on']), 'url' => (string) ($stored['webhook']['url'] ?? '')], 'events' => $events, ]; } /** @param mixed $input */ public function save($input): array { $in = is_array($input) ? $input : []; $current = $this->get(); $email = is_array($in['email'] ?? null) ? $in['email'] + $current['email'] : $current['email']; $webhook = is_array($in['webhook'] ?? null) ? $in['webhook'] + $current['webhook'] : $current['webhook']; $to = self::recipients((string) $email['to']); if (!empty($email['on']) && $to === []) { throw new RelayError('notify.email_invalid', esc_html__('Enter at least one valid email address.', 'siterelay')); } $url = trim((string) $webhook['url']); if ($url !== '' && !preg_match('#^https?://[^\s/?\#]+#i', $url)) { throw new RelayError('notify.webhook_invalid', esc_html__('The webhook URL must start with https:// (or http://).', 'siterelay')); } if (!empty($webhook['on']) && $url === '') { throw new RelayError('notify.webhook_invalid', esc_html__('Enter the webhook URL.', 'siterelay')); } $events = []; foreach (self::EVENTS as $event) { $events[$event] = array_key_exists($event, (array) ($in['events'] ?? [])) ? !empty($in['events'][$event]) : $current['events'][$event]; } $value = ['email' => ['on' => !empty($email['on']), 'to' => implode(', ', $to)], 'webhook' => ['on' => !empty($webhook['on']), 'url' => esc_url_raw($url)], 'events' => $events]; update_site_option(self::OPTION, $value); return $this->get(); } /** @return string[] valid addresses from "a@x.org, b@y.org" (commas, semicolons or spaces) */ public static function recipients(string $list): array { $out = []; foreach (preg_split('/[\s,;]+/', $list) ?: [] as $address) { $address = sanitize_email($address); if ($address !== '' && is_email($address) && !in_array($address, $out, true)) { $out[] = $address; } } return array_slice($out, 0, self::MAX_RECIPIENTS); } }