$schema * @param array $settings * @return string|null Null where the type selects nothing at all. */ public static function of(array $schema, array $settings): ?string { $selects = false; $named = []; foreach ($schema as $key => $field) { if (!is_array($field) || ($field['type'] ?? null) !== self::SELECTS) { continue; } // **Set by the SCHEMA and never by the settings**, which is the // whole of the `null`/`''` distinction: a type that offers a // selector has one whether or not the merchant has used it. $selects = true; $chosen = $settings[$key] ?? []; $labels = self::labels($field); foreach (is_array($chosen) ? $chosen : [] as $id) { if (is_string($id) && $id !== '') { $named[] = $labels[$id] ?? $id; } } } return $selects ? implode(', ', $named) : null; } /** * One field's option ids mapped to their labels, or `[]` where the * provider could not enumerate them. * * @param array $field * @return array */ private static function labels(array $field): array { $labels = []; foreach (is_array($field['options'] ?? null) ? $field['options'] : [] as $option) { if (is_array($option) && isset($option['value'], $option['label'])) { $labels[(string) $option['value']] = (string) $option['label']; } } return $labels; } }