Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .codacy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
exclude_paths:
- ".github/**"
- "example/**"
- "test/**"
26 changes: 7 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
push:
pull_request:

permissions:
contents: read
actions: read

jobs:
composer:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -34,6 +38,7 @@ jobs:
with:
name: build-artifact-${{ matrix.php }}
path: /tmp/github-actions
retention-days: 1

phpunit:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -89,9 +94,10 @@ jobs:
run: cat "_coverage/coverage.txt"

- name: Upload to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: ${{ github.repository }}

phpstan:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -163,21 +169,3 @@ jobs:
php_version: ${{ matrix.php }}
path: src/
standard: phpcs.xml

remove_old_artifacts:
runs-on: ubuntu-latest

permissions:
actions: write

steps:
- name: Remove old artifacts for prior workflow runs on this repository
env:
GH_TOKEN: ${{ github.token }}
run: |
gh api "/repos/${{ github.repository }}/actions/artifacts" | jq ".artifacts[] | select(.name | startswith(\"build-artifact\")) | .id" > artifact-id-list.txt
while read id
do
echo -n "Deleting artifact ID $id ... "
gh api --method DELETE /repos/${{ github.repository }}/actions/artifacts/$id && echo "Done"
done <artifact-id-list.txt
70 changes: 66 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
An interface for objects that expose type-safe getter methods.
==============================================================

Throughout PHP.Gt repositories, wherever an object represents enclosed data, a consistent interface is used to expose the data in a type-safe manner.
Throughout PHP.GT repositories, wherever an object represents enclosed data, a consistent interface is used to expose the data in a type-safe manner.

***

Expand All @@ -18,9 +18,62 @@ Throughout PHP.Gt repositories, wherever an object represents enclosed data, a c
<img src="https://badge.status.php.gt/typesafegetter-version.svg" alt="Current version" />
</a>
<a href="https://www.php.gt/typesafegetter" target="_blank">
<img src="https://badge.status.php.gt/typesafegetter-docs.svg" alt="PHP.Gt/TypeSafeGetter documentation" />
<img src="https://badge.status.php.gt/typesafegetter-docs.svg" alt="PHP.GT/TypeSafeGetter documentation" />
</a>

This package defines:

+ `GT\TypeSafeGetter\TypeSafeGetter`
+ `GT\TypeSafeGetter\NullableTypeSafeGetter`
+ `GT\TypeSafeGetter\CallbackTypeSafeGetter`

The usual pattern is to implement `get()` yourself and use the `NullableTypeSafeGetter` trait for the common typed methods.

```php
use DateTimeImmutable;
use DateTimeInterface;
use GT\TypeSafeGetter\NullableTypeSafeGetter;
use GT\TypeSafeGetter\TypeSafeGetter;

class DataStore implements TypeSafeGetter {
use NullableTypeSafeGetter;

public function __construct(
private readonly array $data = [],
) {}

public function get(string $name):mixed {
return $this->data[$name] ?? null;
}
}

$store = new DataStore([
"id" => "42",
"active" => 1,
"created" => "2024-05-01 09:15:00",
]);

echo $store->getInt("id");
var_dump($store->getBool("active"));
echo $store->getDateTime("created")?->format("Y-m-d");
```

`getInstance()` returns an existing object after checking its type:

```php
$store = new DataStore([
"date" => new DateTimeImmutable("2024-05-01"),
]);

$date = $store->getInstance("date", DateTimeInterface::class);
```

`getDateTime()` accepts:

+ `DateTimeInterface` instances
+ Unix timestamps
+ date/time strings supported by `DateTimeImmutable`

The following methods are defined by this interface:

+ `get(string $name):mixed` - A non-type-safe getter, used for getting keys that are not of an inbuilt type
Expand All @@ -36,12 +89,21 @@ Common areas you will see this interface used:
+ Database rows
+ User input (from the query string or posted form data)
+ Session and cookie storage
+ PHP.Gt's [DataObject](https://www.php.gt/dataobject) repository.
+ HTTP header collections
+ Configuration objects
+ PHP.GT's [DataObject](https://www.php.gt/dataobject) repository.

`NullableTypeSafeGetter` trait
------------------------------

A lot of repositories within PHP.Gt that utilise this class were repeating the same getter code, so this trait was introduced to remove the repetition. All getter functions of the interface are implemented, introducing a protected helper function `getNullableType` which removes the repetition of checking null values before casting them. The `getNullableType` function also allows a callback to be passed as the type parameter, allowing more complex nullable types to be constructed.
A lot of repositories within PHP.GT that utilise this class were repeating the same getter code, so this trait was introduced to remove the repetition. All getter functions of the interface are implemented, introducing a protected helper function `getNullableType` which removes the repetition of checking null values before casting them. The `getNullableType` function also allows a callback to be passed as the type parameter, allowing more complex nullable types to be constructed.

`CallbackTypeSafeGetter` interface
----------------------------------

This interface is for callback-driven lookups where a value may need to be fetched or computed as part of the read operation, such as cache APIs.

Unlike `NullableTypeSafeGetter`, there is no trait implementation in this package for the callback interface. Implementing classes define their own callback behaviour.

# Proudly sponsored by

Expand Down
20 changes: 19 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,32 @@
}
],

"scripts": {
"phpunit": "vendor/bin/phpunit --configuration phpunit.xml",
"phpstan": "vendor/bin/phpstan analyse --level 6 src --memory-limit 256M",
"phpcs": "vendor/bin/phpcs src --standard=phpcs.xml",
"phpmd": "vendor/bin/phpmd src/ text phpmd.xml",
"test": [
"@phpunit",
"@phpstan",
"@phpcs",
"@phpmd"
]
},

"autoload": {
"psr-4": {
"GT\\TypeSafeGetter\\": "./src",
"Gt\\TypeSafeGetter\\": "./src"
}
},
"autoload-dev": {
"psr-4": {
"Gt\\TypeSafeGetter\\Test\\": "./test/phpunit"
"GT\\TypeSafeGetter\\Test\\": "./test/phpunit"
}
},
"config": {
"platform": {
}
}
}
Loading
Loading