Title: AbstractDataTransferObject
Published: May 20, 2026

---

# class AbstractDataTransferObject {}

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#description)
 * [Methods](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#methods)
 * [Source](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#source)
 * [Changelog](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#wp--skip-link--target)

Abstract base class for all Data Value Objects in the AI Client.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#description)󠁿

This abstract class consolidates the common functionality needed by all data transfer
objects:

 * Array transformation for data manipulation
 * JSON schema support for validation and documentation
 * JSON serialization with proper empty object handling

All DTOs in the AI Client should extend this class to ensure consistent behavior
across the codebase.

## 󠀁[Methods](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#methods)󠁿

| Name | Description | 
| [AbstractDataTransferObject::convertEmptyArraysToObjects](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/convertemptyarraystoobjects/) | Recursively converts empty arrays to stdClass objects where the schema expects objects. | 
| [AbstractDataTransferObject::isArrayShape](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/isarrayshape/) | {@inheritDoc} | 
| [AbstractDataTransferObject::jsonSerialize](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/jsonserialize/) | Converts the object to a JSON-serializable format. | 
| [AbstractDataTransferObject::validateFromArrayData](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/validatefromarraydata/) | Validates that required keys exist in the array data. |

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#source)󠁿

    ```php
    abstract class AbstractDataTransferObject implements WithArrayTransformationInterface, WithJsonSchemaInterface, JsonSerializable
    {
        /**
         * Validates that required keys exist in the array data.
         *
         * @since 0.1.0
         *
         * @param array<mixed> $data The array data to validate.
         * @param string[] $requiredKeys The keys that must be present.
         * @throws InvalidArgumentException If any required key is missing.
         */
        protected static function validateFromArrayData(array $data, array $requiredKeys): void
        {
            $missingKeys = [];
            foreach ($requiredKeys as $key) {
                if (!array_key_exists($key, $data)) {
                    $missingKeys[] = $key;
                }
            }
            if (!empty($missingKeys)) {
                throw new InvalidArgumentException(sprintf('%s::fromArray() missing required keys: %s', static::class, implode(', ', $missingKeys)));
            }
        }
        /**
         * {@inheritDoc}
         *
         * @since 0.1.0
         */
        public static function isArrayShape(array $array): bool
        {
            try {
                /** @var TArrayShape $array */
                static::fromArray($array);
                return \true;
            } catch (InvalidArgumentException $e) {
                return \false;
            }
        }
        /**
         * Converts the object to a JSON-serializable format.
         *
         * This method uses the toArray() method and then processes the result
         * based on the JSON schema to ensure proper object representation for
         * empty arrays.
         *
         * @since 0.1.0
         *
         * @return mixed The JSON-serializable representation.
         */
        #[\ReturnTypeWillChange]
        public function jsonSerialize()
        {
            $data = $this->toArray();
            $schema = static::getJsonSchema();
            return $this->convertEmptyArraysToObjects($data, $schema);
        }
        /**
         * Recursively converts empty arrays to stdClass objects where the schema expects objects.
         *
         * @since 0.1.0
         *
         * @param mixed $data The data to process.
         * @param array<mixed, mixed> $schema The JSON schema for the data.
         * @return mixed The processed data.
         */
        private function convertEmptyArraysToObjects($data, array $schema)
        {
            // If data is an empty array and schema expects object, convert to stdClass
            if (is_array($data) && empty($data) && isset($schema['type']) && $schema['type'] === 'object') {
                return new stdClass();
            }
            // If data is an array with content, recursively process nested structures
            if (is_array($data)) {
                // Handle object properties
                if (isset($schema['properties']) && is_array($schema['properties'])) {
                    foreach ($data as $key => $value) {
                        if (isset($schema['properties'][$key]) && is_array($schema['properties'][$key])) {
                            $data[$key] = $this->convertEmptyArraysToObjects($value, $schema['properties'][$key]);
                        }
                    }
                }
                // Handle array items
                if (isset($schema['items']) && is_array($schema['items'])) {
                    foreach ($data as $index => $item) {
                        $data[$index] = $this->convertEmptyArraysToObjects($item, $schema['items']);
                    }
                }
                // Handle oneOf/anyOf schemas - just use the first one
                foreach (['oneOf', 'anyOf'] as $keyword) {
                    if (isset($schema[$keyword]) && is_array($schema[$keyword])) {
                        foreach ($schema[$keyword] as $possibleSchema) {
                            if (is_array($possibleSchema)) {
                                return $this->convertEmptyArraysToObjects($data, $possibleSchema);
                            }
                        }
                    }
                }
            }
            return $data;
        }
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/php-ai-client/src/common/abstractdatatransferobject.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/php-ai-client/src/Common/AbstractDataTransferObject.php#L28)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/php-ai-client/src/Common/AbstractDataTransferObject.php#L28-L128)

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wordpress-aiclient-common-abstractdatatransferobject/?output_format=md#changelog)󠁿

| Version | Description | 
| [0.1.0](https://developer.wordpress.org/reference/since/0.1.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwordpress-aiclient-common-abstractdatatransferobject%2F)
before being able to contribute a note or feedback.