Skip to content

Commit

Permalink
Merge pull request #56 from karriereat/dev/php-82
Browse files Browse the repository at this point in the history
Add PHP 8.2. Support
  • Loading branch information
lentex committed Mar 1, 2023
2 parents e40e603 + 91f6a20 commit 20583a8
Show file tree
Hide file tree
Showing 46 changed files with 1,050 additions and 1,085 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:

strategy:
fail-fast: true
matrix:
php: [ "8.0", "8.1", "8.2" ]

runs-on: ubuntu-latest
name: PHP@${{ matrix.php }}

steps:
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}

- uses: actions/checkout@v3

- name: Validate composer.json and composer.lock
run: composer validate

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest

- name: Lint code
run: composer run-script lint

- name: Analyse code
run: composer run-script analyse

- name: Test code
run: composer run-script test
37 changes: 0 additions & 37 deletions .github/workflows/lint.yml

This file was deleted.

34 changes: 0 additions & 34 deletions .github/workflows/test.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
vendor/
coverage/
composer.lock
.phpunit.result.cache
.php-cs-fixer.cache
coverage.xml
junit.xml
27 changes: 0 additions & 27 deletions .php-cs-fixer.php

This file was deleted.

16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.0.0] - 2023-03-01
### Added
- Support for PHP 8.2.
- Support for typed properties (in addition to the annotated properties)
- [BREAKING] Type hints and return types

### Changed
- [BREAKING] Constructor order of `Bindings`
- [BREAKING] Argument order of `transform` and `transferRaw` in `JsonDecoder`
- Set dynamic properties only if `AllowDynamicProperties` attribute is set (on PHP 8.2. and greater)
- Linting to `pint`
- Unit tests to `pest`

### Removed
- Support for PHP 7.4.

## [4.2.0] - 2022-11-11
### Added
- Support for using array-keys in `ArrayBinding` (#52, #55)
Expand Down
49 changes: 30 additions & 19 deletions readme.md → README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<a href="https://www.karriere.at/" target="_blank"><img width="200" src="https://raw.githubusercontent.com/karriereat/.github/main/profile/logo.svg"></a>
<span>&nbsp;&nbsp;&nbsp;</span>
![](https://github.com/karriereat/json-decoder/workflows/test/badge.svg)
![](https://github.com/karriereat/json-decoder/workflows/lint/badge.svg)
![](https://github.com/karriereat/json-decoder/workflows/CI/badge.svg)
[![Packagist Downloads](https://img.shields.io/packagist/dt/karriere/json-decoder.svg?style=flat-square)](https://packagist.org/packages/karriere/json-decoder)

# JsonDecoder for PHP

Expand All @@ -19,7 +19,7 @@ composer require karriere/json-decoder

By default the Decoder will iterate over all JSON fields defined and will try to set this values on the given class type instance. This change in behavior allows the use of `json-decoder` on classes that use the **magic** `__get` and `__set` functions like Laravel's Eloquent models.

If a property equally named like the JSON field is found or a explicit `Binding` is defined for the JSON field it will be decoded into the defined place. Otherwise the property will just be created and assigned.
If a property equally named like the JSON field is found or a explicit `Binding` is defined for the JSON field it will be decoded into the defined place. Otherwise the property will just be created and assigned (you need the `#[AllowDynamicProperties]` attribute if you are on PHP 8.2.).

The `JsonDecoder` class can receive one parameter called `shouldAutoCase`. If set to true it will try to find the camel-case version from either snake-case or kebap-case automatically if no other binding was registered for the field and it will use an `AliasBinding` if one of the variants can be found.

Expand All @@ -28,36 +28,47 @@ The `JsonDecoder` class can receive one parameter called `shouldAutoCase`. If se
Assume you have a class `Person` that looks like this:

```php
#[AllowDynamicProperties]
class Person
{
public $id;
public $name;
public int $id;
public string $name;
public ?string $lastname = '';
}
```

The following code will transform the given JSON data into an instance of `Person`.

```php
$jsonDecoder = new JsonDecoder();
$jsonData = '{"id": 1, "name": "John Doe"}';
$jsonData = '{"id": 1, "name": "John Doe", "lastname": null, "dynamicProperty": "foo"}';

$person = $jsonDecoder->decode($jsonData, Person::class);
```

Please be aware that since PHP 8.2. dynamic properties are deprecated. So if you still wish to have the ability to make
use of those dynamic properties you have to add the PHP attribute `AllowDynamicProperties` to your class.
If you are using PHP 8.2. (and greater) and don't use the `AllowDynamicProperties` attribute all dynamic properties will
be ignored.

### More complex use case

Let's extend the previous example with a property called address. This address field should contain an instance of `Address`. In the prior versions of `json-decoder` it was necessary to define a custom `Transformer` to be able to handle this situation. As of version 4 you can use the introduced method `scanAndRegister` to automatically generate the transformer based on class annotations.
Let's extend the previous example with a property called address. This address field should contain an instance of `Address`.
As of version 4 you can use the introduced method `scanAndRegister` to automatically generate the transformer based on class annotations.
Since version 5 you can also make use of the property type instead of a class annotation.

```php
class Person
{
public $id;
public $name;
public int $id;
public string $name;

/**
* @var Address
*/
public $address;

public ?Address $typedAddress = null;
}
```

Expand All @@ -67,7 +78,7 @@ For this class definition we can decode JSON data as follows:
$jsonDecoder = new JsonDecoder();
$jsonDecoder->scanAndRegister(Person::class);

$jsonData = '{"id": 1, "name": "John Doe", "address": {"street": "Samplestreet", "city": "Samplecity"}}';
$jsonData = '{"id": 1, "name": "John Doe", "address": {"street": "Samplestreet", "city": "Samplecity"}, , "typedAddress": {"street": "Samplestreet", "city": "Samplecity"}}';

$person = $jsonDecoder->decode($jsonData, Person::class);
```
Expand All @@ -79,9 +90,9 @@ If you don't use annotations or need a more flexible `Transformer` you can also
```php
class Person
{
public $id;
public $name;
public $address;
public int $id;
public string $name;
public mixed $address;
}
```

Expand Down Expand Up @@ -153,19 +164,19 @@ Defines a JSON field to property binding for the given type.
**Signature:**

```php
new FieldBinding($property, $jsonField, $type);
new FieldBinding(string $property, ?string $jsonField = null, ?string $type = null, bool $isRequired = false);
```

This defines a field mapping for the property `$property` to a class instance of type `$type` with data in `$jsonField`.

#### ArrayBinding

Defines a array field binding for the given type.
Defines an array field binding for the given type.

**Signature:**

```php
new ArrayBinding($property, $jsonField, $type);
new ArrayBinding(string $property, ?string $jsonField = null, ?string $type = null, bool $isRequired = false);
```

This defines a field mapping for the property `$property` to an array of class instance of type `$type` with data in `$jsonField`.
Expand All @@ -177,7 +188,7 @@ Defines a JSON field to property binding.
**Signature:**

```php
new AliasBinding($property, $jsonField);
new AliasBinding(string $property, ?string $jsonField = null, bool $isRequired = false);
```

#### DateTimeBinding
Expand All @@ -187,7 +198,7 @@ Defines a JSON field to property binding and converts the given string to a `Dat
**Signature:**

```php
new new DateTimeBinding($property, $jsonField, $isRequired = false, $dateTimeFormat = DateTime::ATOM);
new DateTimeBinding(string $property, ?string $jsonField = null, bool $isRequired = false, $dateTimeFormat = DateTime::ATOM);
```

#### CallbackBinding
Expand All @@ -197,7 +208,7 @@ Defines a property binding that gets the callback result set as its value.
**Signature:**

```php
new CallbackBinding($property, $callback);
new CallbackBinding(string $property, private Closure $callback);
```

## License
Expand Down

0 comments on commit 20583a8

Please sign in to comment.