| | |
| | | public ?string $contentType; // tattoo, artist, style (without BASE prefix) |
| | | public ?object $wpObject; // WP_Post, WP_Term, WP_User |
| | | |
| | | /** @var array<string, Field> */ |
| | | /** @var array<string, Field> Loaded fields */ |
| | | public array $fields = []; |
| | | |
| | | /** @var array<string, array> Raw field configs from registry */ |
| | | public array $fieldConfigs = []; |
| | | |
| | | public ?string $baseKey = null; // For options |
| | | /** @var string|null Base key for options storage */ |
| | | public ?string $baseKey = null; |
| | | |
| | | /** |
| | | * WordPress default fields by object type |
| | | */ |
| | | public const WP_DEFAULTS = [ |
| | | 'post' => [ |
| | | 'post_title', |
| | |
| | | 'user_email', |
| | | ], |
| | | 'term' => [ |
| | | 'term_name', |
| | | 'name', |
| | | 'description' |
| | | ] |
| | | ]; |
| | |
| | | $this->contentType = $contentType; |
| | | } |
| | | |
| | | /** |
| | | * Check if field exists in configs |
| | | */ |
| | | public function hasField(string $name): bool |
| | | { |
| | | return isset($this->fields[$name]) || isset($this->fieldConfigs[$name]); |
| | | } |
| | | |
| | | /** |
| | | * Get loaded field instance |
| | | */ |
| | | public function getField(string $name): ?Field |
| | | { |
| | | return $this->fields[$name] ?? null; |
| | | } |
| | | |
| | | /** |
| | | * Set/add a field instance |
| | | */ |
| | | public function setField(Field $field): self |
| | | { |
| | | $this->fields[$field->name] = $field; |
| | | return $this; |
| | | } |
| | | |
| | | public function getFieldConfig(string $name): ?array |
| | | /** |
| | | * Remove a field instance |
| | | */ |
| | | public function removeField(string $name): self |
| | | { |
| | | return $this->fieldConfigs[$name] ?? null; |
| | | unset($this->fields[$name]); |
| | | return $this; |
| | | } |
| | | |
| | | /** |
| | | * Get field configuration |
| | | */ |
| | | public function getFieldConfig(string $name): ?array |
| | | { |
| | | if (isset($this->fieldConfigs[$name])) { |
| | | return $this->fieldConfigs[$name]; |
| | | } |
| | | |
| | | // Search nested fields (repeaters, groups) |
| | | foreach ($this->fieldConfigs as $config) { |
| | | if (isset($config['fields'][$name])) { |
| | | return $config['fields'][$name]; |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * Check if field is a WordPress default |
| | | */ |
| | | public function isWpDefault(string $name): bool |
| | | { |
| | | $defaults = self::WP_DEFAULTS[$this->objectType] ?? []; |
| | | return in_array($name, $defaults, true); |
| | | } |
| | | |
| | | /** |
| | | * Get all dirty (changed) fields |
| | | * @return array<string, Field> |
| | | */ |
| | | public function getDirtyFields(): array |
| | | { |
| | | return array_filter($this->fields, fn(Field $f) => $f->isDirty); |
| | | } |
| | | |
| | | /** |
| | | * Get all invalid fields |
| | | * @return array<string, Field> |
| | | */ |
| | | public function getInvalidFields(): array |
| | | { |
| | | return array_filter($this->fields, fn(Field $f) => !$f->isValid); |
| | | } |
| | | |
| | | /** |
| | | * Mark all loaded fields as clean |
| | | */ |
| | | public function markAllClean(): self |
| | | { |
| | | foreach ($this->fields as $field) { |
| | |
| | | return $this; |
| | | } |
| | | |
| | | /** |
| | | * Reset all fields to original values |
| | | */ |
| | | public function resetAll(): self |
| | | { |
| | | foreach ($this->fields as $field) { |
| | | $field->reset(); |
| | | } |
| | | return $this; |
| | | } |
| | | |
| | | /** |
| | | * Check if any fields are dirty |
| | | */ |
| | | public function hasDirtyFields(): bool |
| | | { |
| | | return !empty($this->getDirtyFields()); |
| | | } |
| | | |
| | | /** |
| | | * Check if all fields are valid |
| | | */ |
| | | public function isValid(): bool |
| | | { |
| | | return empty($this->getInvalidFields()); |
| | | } |
| | | |
| | | /** |
| | | * Get all field names from configs |
| | | */ |
| | | public function getFieldNames(): array |
| | | { |
| | | return array_keys($this->fieldConfigs); |
| | | } |
| | | |
| | | /** |
| | | * Get loaded field values as array |
| | | */ |
| | | public function toArray(): array |
| | | { |
| | | $data = []; |
| | | foreach ($this->fields as $name => $field) { |
| | | $data[$name] = $field->value; |
| | | } |
| | | return $data; |
| | | } |
| | | } |