-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAddressFieldSet.php
More file actions
118 lines (107 loc) · 4.08 KB
/
Copy pathAddressFieldSet.php
File metadata and controls
118 lines (107 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php namespace johnbarrett\Google_Address_Autocomplete;
/**
* One configured address field set. REDCap hands sub-settings back as a plain array per
* set; this turns one of those into a checked, named shape once, at the boundary.
*/
final readonly class AddressFieldSet
{
public function __construct(
/** Position in config.json, 0-based. Fixes this set's element-id prefix. */
public int $index,
public string $description,
public bool $disabled,
public array $forms,
/** Numeric REDCap event ids, as strings. Empty means every event. */
public array $events,
public string $autocomplete,
public string $streetNumber,
public string $street,
public string $city,
public string $county,
public string $state,
public string $zip,
public string $country,
public string $latitude,
public string $longitude,
public string $placeName,
public bool $recoverUnit,
public string $regionCodes,
public string $primaryTypes,
) {}
/**
* Sub-settings are stored flat, one parallel array per child key, so a key added to
* config.json after a project was configured is simply absent from the array REDCap
* returns. No parameter here may become required.
*/
public static function fromSubSetting(array $raw, int $index): self
{
return new self(
index: $index,
description: self::text($raw, 'set-description'),
disabled: !empty($raw['set-disabled']),
forms: self::stringList($raw, 'set-form'),
events: self::stringList($raw, 'set-event'),
// Trimmed like every other field name: a trailing space typed into the setting
// would otherwise pass every server-side check and then match no element.
autocomplete: self::text($raw, 'set-autocomplete'),
streetNumber: self::text($raw, 'set-street-number'),
street: self::text($raw, 'set-street'),
city: self::text($raw, 'set-city'),
county: self::text($raw, 'set-county'),
state: self::text($raw, 'set-state'),
zip: self::text($raw, 'set-zip'),
country: self::text($raw, 'set-country'),
latitude: self::text($raw, 'set-latitude'),
longitude: self::text($raw, 'set-longitude'),
placeName: self::text($raw, 'set-place-name'),
recoverUnit: !empty($raw['set-recover-unit']),
regionCodes: (string)($raw['set-region-codes'] ?? ''),
primaryTypes: (string)($raw['set-primary-types'] ?? ''),
);
}
private static function text(array $raw, string $key): string
{
return trim((string)($raw[$key] ?? ''));
}
/**
* A child-level repeatable list (REDCap's multi-value picker, not instance repetition),
* which comes back as a bare scalar when only one entry is chosen.
*
* Everything is cast to string. That is what lets appliesToEvent() compare strictly: an
* event-list stores numeric ids, and the hook hands us an int, so without this the two
* sides would never match.
*/
private static function stringList(array $raw, string $key): array
{
$values = $raw[$key] ?? [];
if (!is_array($values)) { $values = [$values]; }
$values = array_map(trim(...), array_map(strval(...), $values));
return array_values(array_filter($values, static fn(string $value): bool => $value !== ''));
}
public function isActive(): bool
{
return !$this->disabled && $this->autocomplete !== '';
}
public function appliesTo(string $instrument): bool
{
return !$this->forms || in_array($instrument, $this->forms, true);
}
/**
* Blank scope means every event, which is what keeps classic projects and every set
* configured before this setting existed working unchanged. Strict comparison is safe
* because stringList() normalised the configured side to string and the caller casts.
*/
public function appliesToEvent(string $eventId): bool
{
return !$this->events || in_array($eventId, $this->events, true);
}
public function label(): string
{
return '#' . ($this->index + 1) . ($this->description !== '' ? ' ' . $this->description : '');
}
/** Element-id prefix. Unique per set — this is what keeps two sets apart. */
public function elementPrefix(): string
{
return 'googleSearch_' . $this->index . '_';
}
}