Jake Vanderwerf
8 days ago 3b83905603d44b1a08f8b2b36a605808ce686ad6
inc/meta/Item.php
@@ -16,14 +16,18 @@
   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',
@@ -43,7 +47,7 @@
         'user_email',
      ],
      'term' => [
         'term_name',
         'name',
         'description'
      ]
   ];
@@ -58,43 +62,89 @@
      $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) {
@@ -103,13 +153,50 @@
      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;
   }
}