diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d0ae48d..41e9ce7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: uses: ramsey/composer-install@v2 - name: Run tests with coverage results - run: vendor/bin/phpunit --coverage-clover ./tests/output/clover.xml + run: vendor/bin/phpunit --coverage-clover ./tests/_output/clover.xml - name: Upload coverage results to Coveralls env: @@ -41,7 +41,7 @@ jobs: COVERALLS_FLAG_NAME: ${{ matrix.php }} run: | composer require php-coveralls/php-coveralls -n - vendor/bin/php-coveralls --coverage_clover=./tests/output/clover.xml -v --json_path=./tests/output/coveralls-upload.json + vendor/bin/php-coveralls --coverage_clover=./tests/_output/clover.xml -v --json_path=./tests/_output/coveralls-upload.json finish: name: Close parallel build needs: tests diff --git a/.gitignore b/.gitignore index dae6bed..86acf06 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ vendor docker/.env .phpunit.result.cache -/tests/output -!/tests/output/.gitkeep \ No newline at end of file +/tests/_output +!/tests/_output/.gitkeep \ No newline at end of file diff --git a/README.md b/README.md index 0e68913..1c7f5f1 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,36 @@ $color = $nestedDto->getColor(); // ColorEnum::Red $colorValue = $colorEnum->value; // 'red' ``` +#### Return DTO as array + +```php + 5, + 'providerName' => 'Main Provider', +]; + +$dto = new SnakeCaseDto($data); + +$array = $dto->toArray(); // ['actualNumber' => 5, 'providerName' => 'Main Provider'] +$arrayWithSnakeCaseKeys = $dto->toArray(rawKeys: false); // ['actual_number' => 5, 'provider_name' => 'Main Provider'] +``` + ## For developers ### Requirements @@ -340,4 +370,5 @@ The [php-dto](https://github.com/PetrenkoAnton/php-dto/) library is open-sourced ## Related projects +- [PetrenkoAnton/key-normalizer](https://github.com/PetrenkoAnton/key-normalizer) - [PetrenkoAnton/php-collection](https://github.com/PetrenkoAnton/php-collection) \ No newline at end of file diff --git a/VERSION b/VERSION index 8428158..867e524 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.2 \ No newline at end of file +1.2.0 \ No newline at end of file diff --git a/composer.json b/composer.json index 159df90..257befd 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ ], "require": { "php": "^8.1", - "petrenkoanton/php-collection": "^1.0" + "petrenkoanton/php-collection": "^1.0", + "petrenkoanton/key-normalizer": "^2.0" }, "require-dev": { "phpunit/phpunit": "^9.0", diff --git a/composer.lock b/composer.lock index 1522c29..a058bf8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,63 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5abe8febbc82f02ad890accd90b78452", + "content-hash": "d70aa36a4d41dae6fc219b00760e843e", "packages": [ + { + "name": "petrenkoanton/key-normalizer", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/PetrenkoAnton/key-normalizer.git", + "reference": "ed0442d85c04501689d4a113b0775574b6684374" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PetrenkoAnton/key-normalizer/zipball/ed0442d85c04501689d4a113b0775574b6684374", + "reference": "ed0442d85c04501689d4a113b0775574b6684374", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.7", + "phpunit/phpunit": "^9.0", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.1", + "squizlabs/php_codesniffer": "^3.8", + "vimeo/psalm": "^5.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "KeyNormalizer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Petrenko", + "email": "antptrnk@gmail.com", + "homepage": "https://github.com/petrenkoanton", + "role": "Developer" + } + ], + "description": "Converts snake_case to camelCase and vice versa", + "keywords": [ + "camel case", + "helper", + "snake case" + ], + "support": { + "issues": "https://github.com/PetrenkoAnton/key-normalizer/issues", + "source": "https://github.com/PetrenkoAnton/key-normalizer/tree/v2.0.0" + }, + "time": "2024-02-20T14:29:47+00:00" + }, { "name": "petrenkoanton/php-collection", "version": "v1.1.2", diff --git a/docker/.env.example b/docker/.env.example index 5cb6c59..794b3d9 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -1 +1,6 @@ -CONTAINER_NAME=php-dto \ No newline at end of file +CONTAINER_NAME=php-dto +XDEBUG_SESSION=PHPSTORM +XDEBUG_IDE_KEY=PHPSTORM +XDEBUG_SERVER_NAME=localhost +XDEBUG_CLIENT_HOST=host.docker.internal +XDEBUG_START_WITH_REQUEST=trigger # yes | no | trigger \ No newline at end of file diff --git a/docker/docker-compose-php81.yml b/docker/docker-compose-php81.yml index 01b54f0..aa396c0 100644 --- a/docker/docker-compose-php81.yml +++ b/docker/docker-compose-php81.yml @@ -6,13 +6,15 @@ services: restart: unless-stopped working_dir: /var/www/ environment: - - XDEBUG_SESSION=PHPSTORM - - PHP_IDE_CONFIG=serverName=localhost + XDEBUG_SESSION: ${XDEBUG_SESSION} + PHP_IDE_CONFIG: serverName=${XDEBUG_SERVER_NAME} + XDEBUG_CONFIG: "ide_key=${XDEBUG_IDE_KEY} client_host=${XDEBUG_CLIENT_HOST} start_with_request=${XDEBUG_START_WITH_REQUEST}" volumes: - ./../:/var/www - ./ini/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - ./ini/php-opcache.ini:/usr/local/etc/php/conf.d/opcache.ini - ./ini/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini + - ./../tests/_output:/opt/phpstorm-coverage/ networks: - default diff --git a/docker/docker-compose-php82.yml b/docker/docker-compose-php82.yml index 831de33..1f580f3 100644 --- a/docker/docker-compose-php82.yml +++ b/docker/docker-compose-php82.yml @@ -6,13 +6,15 @@ services: restart: unless-stopped working_dir: /var/www/ environment: - - XDEBUG_SESSION=PHPSTORM - - PHP_IDE_CONFIG=serverName=localhost + XDEBUG_SESSION: ${XDEBUG_SESSION} + PHP_IDE_CONFIG: serverName=${XDEBUG_SERVER_NAME} + XDEBUG_CONFIG: "ide_key=${XDEBUG_IDE_KEY} client_host=${XDEBUG_CLIENT_HOST} start_with_request=${XDEBUG_START_WITH_REQUEST}" volumes: - ./../:/var/www - ./ini/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - ./ini/opcache.ini:/usr/local/etc/php/conf.d/docker-php-ext-opcache.ini - ./ini/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini + - ./../tests/_output:/opt/phpstorm-coverage/ networks: - default diff --git a/docker/docker-compose-php83.yml b/docker/docker-compose-php83.yml index 2d35744..3a138b1 100644 --- a/docker/docker-compose-php83.yml +++ b/docker/docker-compose-php83.yml @@ -6,13 +6,15 @@ services: restart: unless-stopped working_dir: /var/www/ environment: - - XDEBUG_SESSION=PHPSTORM - - PHP_IDE_CONFIG=serverName=localhost + XDEBUG_SESSION: ${XDEBUG_SESSION} + PHP_IDE_CONFIG: serverName=${XDEBUG_SERVER_NAME} + XDEBUG_CONFIG: "ide_key=${XDEBUG_IDE_KEY} client_host=${XDEBUG_CLIENT_HOST} start_with_request=${XDEBUG_START_WITH_REQUEST}" volumes: - ./../:/var/www - ./ini/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - ./ini/opcache.ini:/usr/local/etc/php/conf.d/docker-php-ext-opcache.ini - ./ini/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini + - ./../tests/_output:/opt/phpstorm-coverage/ networks: - default diff --git a/psalm.xml b/psalm.xml index 1a3425c..df94f78 100644 --- a/psalm.xml +++ b/psalm.xml @@ -20,7 +20,7 @@ - + diff --git a/src/Dto.php b/src/Dto.php index 9f48a52..a9c33fa 100644 --- a/src/Dto.php +++ b/src/Dto.php @@ -22,6 +22,7 @@ use Dto\Exception\Internal\EnumBackingValueException; use Error; use InvalidArgumentException; +use KeyNormalizer\KeyNormalizer; use ReflectionClass; use ReflectionException; use ReflectionNamedType; @@ -112,7 +113,7 @@ public function __call(string $name, array $arguments): mixed return $this->{$property}; } - public function toArray(): array + public function toArray(KeyCase $keyCase = KeyCase::CAMEL_CASE): array { $properties = (new ReflectionClass($this))->getProperties(ReflectionProperty::IS_PROTECTED); @@ -123,8 +124,13 @@ public function toArray(): array $property->setAccessible(true); $value = $property->getValue($this); - $data[$property->getName()] = is_a($value, Arrayable::class) - ? $value->toArray() + $key = match ($keyCase) { + KeyCase::SNAKE_CASE => KeyNormalizer::toSnakeCase($property->getName()), + KeyCase::CAMEL_CASE => $property->getName(), + }; + + $data[$key] = is_a($value, Arrayable::class) + ? is_a($value, self::class) ? $value->toArray($keyCase) : $value->toArray() : $value; } diff --git a/src/KeyCase.php b/src/KeyCase.php new file mode 100644 index 0000000..222440c --- /dev/null +++ b/src/KeyCase.php @@ -0,0 +1,11 @@ + [ + 'actualNumber' => 5, + 'listInfo' => ['First random string', 'Second random string'], + 'infoArrayable' => new InfoArrayable(), + ], + 'actualNumber' => 10, + 'providerName' => 'Main provider', + ]; + + $dto = new SnakeCaseNestedDto($data); + $this->assertEquals($expected, $dto->toArray($keyCase)); + } + + public static function dpTestToArray(): array + { + return [ + [ + KeyCase::CAMEL_CASE, + [ + 'snakeCase' => [ + 'actualNumber' => 5, + 'listInfo' => ['First random string', 'Second random string'], + 'infoArrayable' => ['camelCaseKey' => 'value'], + ], + 'actualNumber' => 10, + 'providerName' => 'Main provider', + ], + ], + [ + KeyCase::SNAKE_CASE, + [ + 'snake_case' => [ + 'actual_number' => 5, + 'list_info' => ['First random string', 'Second random string'], + 'info_arrayable' => ['camelCaseKey' => 'value'], + ], + 'actual_number' => 10, + 'provider_name' => 'Main provider', + ], + ], + ]; + } } diff --git a/tests/Fixtures/InfoArrayable.php b/tests/Fixtures/InfoArrayable.php index e597808..c69b305 100644 --- a/tests/Fixtures/InfoArrayable.php +++ b/tests/Fixtures/InfoArrayable.php @@ -10,6 +10,6 @@ class InfoArrayable implements Arrayable { public function toArray(): array { - return ['key' => 'value']; + return ['camelCaseKey' => 'value']; } } diff --git a/tests/Fixtures/SnakeCaseDto.php b/tests/Fixtures/SnakeCaseDto.php new file mode 100644 index 0000000..eb45160 --- /dev/null +++ b/tests/Fixtures/SnakeCaseDto.php @@ -0,0 +1,21 @@ +