admin(); } else if ($context === Registry::CONTEXT_OFFERING_HOST) { $recipients = $this->hosts($booking); } else if ($context === Registry::CONTEXT_PRIMARY_BOOKER) { $recipients = $this->primaryBooker($booking); } else if ($context === Registry::CONTEXT_REGISTRANT) { $recipients = $this->registrants($booking); } else if ($context === Registry::CONTEXT_CUSTOM) { $recipients = $this->picker((array) ($template['to'] ?? [])); } else { $recipients = []; } $recipients = $this->dedupe($recipients, $context); return apply_filters( 'DayTidy/F__DayTidy/Notifications/RecipientResolver__resolve/recipients', $recipients, $booking, $context, $template ); } /** * @param mixed[] $picker * @return mixed[] */ public function picker(array $picker): array { $recipients = []; $users = isset($picker['users']) && is_array($picker['users']) ? array_map('absint', $picker['users']) : []; foreach ($this->users($users) as $recipient) $recipients[] = $recipient; $roles = isset($picker['roles']) && is_array($picker['roles']) ? array_map('sanitize_key', $picker['roles']) : []; foreach ($this->roles($roles) as $recipient) $recipients[] = $recipient; $emails = isset($picker['emails']) ? (string) $picker['emails'] : ''; foreach ($this->emails($emails) as $recipient) $recipients[] = $recipient; return $this->dedupe($recipients, Registry::CONTEXT_CUSTOM); } /** * @return mixed[] */ private function admin(): array { $email = get_option('admin_email'); $name = get_bloginfo('name'); $recipient = $this->recipient((string) $email, (string) $name); return $recipient ? [$recipient] : []; } /** * @return mixed[] */ private function hosts(Booking $booking): array { $offering = $booking->offering(); if (!$offering) return []; $recipients = []; foreach ($offering->getHosts() as $host) { if (!is_object($host) || !method_exists($host, 'email')) continue; $email = (string) $host->email(); $name = method_exists($host, 'name') ? (string) $host->name() : ''; $recipient = $this->recipient($email, $name); if ($recipient) $recipients[] = $recipient; } return $recipients; } /** * @return mixed[] */ private function primaryBooker(Booking $booking): array { $form = $booking->getData()->getMappedForm(); $email = $this->field($form['email'] ?? []); $first = $this->field($form['first_name'] ?? []); $last = $this->field($form['last_name'] ?? []); $name = trim($first . ' ' . $last); $recipient = $this->recipient($email, $name); return $recipient ? [$recipient] : []; } /** * @return mixed[] */ private function registrants(Booking $booking): array { $recipients = []; foreach ($booking->getData()->getMappedParticipants() as $participant) { if (!is_array($participant)) continue; $email = $this->participantEmail($participant); $first = $this->field($participant['first_name'] ?? []); $last = $this->field($participant['last_name'] ?? []); $name = trim($first . ' ' . $last); $recipient = $this->recipient($email, $name, ['participant' => $participant]); if ($recipient) $recipients[] = $recipient; } return $recipients; } /** * @param int[] $ids * @return mixed[] */ private function users(array $ids): array { if (!count($ids)) return []; $recipients = []; $users = get_users([ 'include' => $ids, 'fields' => ['ID', 'display_name', 'user_email'], ]); foreach ($users as $user) { if (!$user instanceof WP_User && !is_object($user)) continue; $recipient = $this->recipient( (string) $user->user_email, (string) $user->display_name, ['user_id' => (int) $user->ID] ); if ($recipient) $recipients[] = $recipient; } return $recipients; } /** * @param string[] $roles * @return mixed[] */ private function roles(array $roles): array { $roles = array_values(array_filter($roles)); if (!count($roles)) return []; $recipients = []; $users = get_users([ 'role__in' => $roles, 'fields' => ['ID', 'display_name', 'user_email'], ]); foreach ($users as $user) { if (!$user instanceof WP_User && !is_object($user)) continue; $recipient = $this->recipient( (string) $user->user_email, (string) $user->display_name, ['user_id' => (int) $user->ID] ); if ($recipient) $recipients[] = $recipient; } return $recipients; } /** * @return mixed[] */ private function emails(string $emails): array { $recipients = []; $items = preg_split('/[\s,;]+/', $emails); if (!$items) return []; foreach ($items as $email) { $recipient = $this->recipient((string) $email); if ($recipient) $recipients[] = $recipient; } return $recipients; } /** * @param mixed[] $field */ private function field(array $field): string { return $this->stringify($field['value'] ?? ''); } /** * @param mixed[] $participant */ private function participantEmail(array $participant): string { if (isset($participant['email']) && is_array($participant['email'])) { return $this->field($participant['email']); } foreach ($participant as $field) { if (!is_array($field)) continue; $value = $this->field($field); $type = (string) ($field['type'] ?? ''); if ($type === 'email' && is_email($value)) return $value; if (is_email($value)) return $value; } return ''; } /** * @param mixed $value */ private function stringify($value): string { if (is_array($value)) { $parts = []; foreach ($value as $item) $parts[] = $this->stringify($item); return implode(', ', array_filter($parts)); } return trim(wp_strip_all_tags((string) $value)); } /** * @param mixed[] $data * @return mixed[]|null */ private function recipient(string $email, string $name = '', array $data = []): ?array { $email = sanitize_email($email); if (!is_email($email)) return null; return [ 'email' => $email, 'name' => sanitize_text_field($name), 'data' => $data, ]; } /** * @param mixed[] $recipients * @return mixed[] */ private function dedupe(array $recipients, string $context): array { $deduped = []; foreach ($recipients as $recipient) { if (!is_array($recipient) || empty($recipient['email'])) continue; $email = strtolower((string) $recipient['email']); if (isset($deduped[$email])) continue; $recipient['context'] = $context; $deduped[$email] = $recipient; } return array_values($deduped); } }