meta = $meta; $this->name = $name; $this->config = $meta->config($name) ?? []; $data = $meta->get($name); $this->data = is_array($data) ? $data : []; } public function get(string $path): mixed { $parts = explode('|', $path); return $this->getPath($this->data, $this->config['fields'] ?? [], $parts); } protected function getPath(array $data, array $fieldsConfig, array $parts): mixed { $key = array_shift($parts); $fieldConfig = $fieldsConfig[$key] ?? false; if (!$fieldConfig) { return ''; } if (empty($parts)) { return $data[$key] ?? $fieldConfig['default'] ?? ''; } $nested = is_array($data[$key] ?? null) ? $data[$key] : []; return $this->getPath($nested, $fieldConfig['fields'] ?? [], $parts); } public function set(string $path, mixed $value, bool $autosave = true): self { $parts = explode('|', $path); $this->setPath($this->data, $this->config['fields'] ?? [], $parts, $value); $this->sync($autosave); return $this; } protected function setPath(array &$data, array $fieldsConfig, array $parts, mixed $value): void { $key = array_shift($parts); $fieldConfig = $fieldsConfig[$key] ?? false; if (!$fieldConfig) { error_log('[Group]::set Could not find child field config: ' . $key); return; } if (empty($parts)) { $data[$key] = $value; return; } // Nested group - descend into it if (!isset($data[$key]) || !is_array($data[$key])) { $data[$key] = []; } $this->setPath($data[$key], $fieldConfig['fields'] ?? [], $parts, $value); } public function setAll(array $data): self { foreach ($data as $field => $value) { $fieldConfig = $this->config['fields'][$field] ?? false; if (!$fieldConfig) { continue; } $this->data[$field] = $value; } $this->sync(true); return $this; } public function all(): array { return $this->data; } public function has(string $field): bool { return isset($this->config['fields'][$field]); } protected function sync(bool $autosave = true): void { $this->meta->set($this->name, $this->data, $autosave); } }