1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace LaravelUi5\OData\Protocol\Execution;
6:
7: use LaravelUi5\OData\Protocol\Planning\ComputedProperty;
8: use LaravelUi5\OData\Protocol\Planning\ExpandList;
9: use LaravelUi5\OData\Protocol\Planning\PropertySelectItem;
10: use LaravelUi5\OData\Protocol\Planning\SelectList;
11:
12: /**
13: * Shared helpers for $select handling in response handlers.
14: */
15: final class SelectHelper
16: {
17: /**
18: * Returns an associative array of allowed column names (name => true),
19: * or null when select-all (*) is in effect.
20: *
21: * Expanded navigation properties are always included regardless of $select.
22: *
23: * @return array<string, true>|null
24: */
25: /**
26: * @param list<ComputedProperty> $compute
27: */
28: public static function allowedKeys(
29: SelectList $select,
30: ExpandList $expand = new ExpandList(),
31: array $compute = [],
32: ): ?array {
33: if ($select->isSelectAll()) {
34: return null;
35: }
36:
37: $keys = [];
38: foreach ($select->items as $item) {
39: if ($item instanceof PropertySelectItem) {
40: $keys[$item->property->getName()] = true;
41: }
42: }
43:
44: // Expanded navigation properties are always present in the response.
45: foreach ($expand->items as $item) {
46: $keys[$item->property->getName()] = true;
47: }
48:
49: // Computed properties are always present in the response.
50: foreach ($compute as $computed) {
51: $keys[$computed->alias] = true;
52: }
53:
54: return $keys;
55: }
56:
57: /**
58: * Returns the OData context URL fragment for a $select clause.
59: *
60: * Empty string when select-all; otherwise "(prop1,prop2,...)".
61: */
62: public static function contextFragment(SelectList $select): string
63: {
64: if ($select->isSelectAll()) {
65: return '';
66: }
67:
68: $names = [];
69: foreach ($select->items as $item) {
70: if ($item instanceof PropertySelectItem) {
71: $names[] = $item->property->getName();
72: }
73: }
74:
75: return $names !== [] ? '(' . implode(',', $names) . ')' : '';
76: }
77: }
78: