Skip to content

Commit

Permalink
:octocat: backport changes from v3.2.1 (https://github.com/chillerlan/php-set…
Browse files Browse the repository at this point in the history
  • Loading branch information
codemasher committed Jul 17, 2024
1 parent 394d569 commit 5553558
Show file tree
Hide file tree
Showing 17 changed files with 260 additions and 173 deletions.
33 changes: 18 additions & 15 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
/.build export-ignore
/.github export-ignore
/.phan export-ignore
/.phpdoc export-ignore
/docs export-ignore
/examples export-ignore
/tests export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.readthedocs.yml export-ignore
/phpcs.xml.dist export-ignore
/phpdoc.xml.dist export-ignore
/phpmd.xml.dist export-ignore
/phpunit.xml.dist export-ignore
/.build export-ignore
/.github export-ignore
/.idea export-ignore
/.phan export-ignore
/.phpdoc export-ignore
/docs export-ignore
/examples export-ignore
/tests export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.readthedocs.yml export-ignore
/phpcs.xml.dist export-ignore
/phpdoc.xml.dist export-ignore
/phpmd.xml.dist export-ignore
/phpunit.xml.dist export-ignore
/phpstan.dist.neon export-ignore
/phpstan-baseline.neon export-ignore

*.php diff=php
38 changes: 22 additions & 16 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
# https://github.com/sebastianbergmann/phpunit/blob/master/.github/workflows/ci.yml

name: "CI"

on:
push:
branches:
Expand All @@ -10,19 +12,17 @@ on:
- v2.x-php7.4


name: "CI"
env:
PHP_EXTENSIONS: json
PHP_INI_VALUES: memory_limit=-1, error_reporting=-1, display_errors=On


jobs:

static-code-analysis:
name: "Static Code Analysis"

runs-on: ubuntu-latest

env:
PHAN_ALLOW_XDEBUG: 0
PHAN_DISABLE_XDEBUG_WARN: 1

strategy:
fail-fast: true
matrix:
Expand All @@ -32,24 +32,25 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
# - "8.4"

steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: "Install PHP"
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: pecl
extensions: ${{ env.PHP_EXTENSIONS }}
ini-values: ${{ env.PHP_INI_VALUES }}
coverage: none
extensions: ast, json

- name: "Update dependencies with composer"
uses: ramsey/composer-install@v2
uses: ramsey/composer-install@v3

- name: "Run phan"
run: php vendor/bin/phan --target-php-version=${{ matrix.php-version }}
- name: "Run PHPStan"
run: php vendor/bin/phpstan


tests:
Expand All @@ -69,26 +70,31 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
# - "8.4"

steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: "Install PHP with extensions"
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: ${{ env.PHP_EXTENSIONS }}
ini-values: ${{ env.PHP_INI_VALUES }}
coverage: pcov
extensions: json

- name: "Install dependencies with composer"
uses: ramsey/composer-install@v2
uses: ramsey/composer-install@v3

- name: "Run tests with phpunit"
run: php vendor/phpunit/phpunit/phpunit --configuration=phpunit.xml.dist

- name: "Send code coverage report to Codecov.io"
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: .build/coverage/clover.xml

- name: "Send code coverage report to Codacy"
uses: codacy/codacy-coverage-reporter-action@v1
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ phpcs.xml
phpdoc.xml
phpmd.xml
phpunit.xml
phpstan.neon
55 changes: 0 additions & 55 deletions .phan/config.php

This file was deleted.

79 changes: 45 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,31 +45,27 @@ Profit!

## Usage

The `SettingsContainerInterface` (wrapped in`SettingsContainerAbstract` ) provides plug-in functionality for immutable object properties and adds some fancy, like loading/saving JSON, arrays etc.
The `SettingsContainerInterface` (wrapped in`SettingsContainerAbstract`) provides plug-in functionality for immutable object properties and adds some fancy, like loading/saving JSON, arrays etc.
It takes an `iterable` as the only constructor argument and calls a method with the trait's name on invocation (`MyTrait::MyTrait()`) for each used trait.

A PHPStan ruleset to exclude errors generated by accessing magic properties on `SettingsContainerInterface` can be found in `rules-magic-access.neon`.


### Simple usage
```php
class MyContainer extends SettingsContainerAbstract{
protected $foo;
protected $bar;
}
```
Typed properties in PHP 7.4+:
```php
class MyContainer extends SettingsContainerAbstract{
protected string $foo;
protected string $bar;
}
```

```php
// use it just like a \stdClass
// use it just like a \stdClass (except the properties are fixed)
$container = new MyContainer;
$container->foo = 'what';
$container->bar = 'foo';

// which is equivalent to
// which is equivalent to
$container = new MyContainer(['bar' => 'foo', 'foo' => 'what']);
// ...or try
$container->fromJSON('{"foo": "what", "bar": "foo"}');
Expand All @@ -90,37 +86,48 @@ var_dump($container->nope); // -> null

### Advanced usage
```php
// from library 1
trait SomeOptions{
protected $foo;
protected $what;
protected string $foo;
protected string $what;

// this method will be called in SettingsContainerAbstract::construct()
// after the properties have been set
protected function SomeOptions(){
protected function SomeOptions():void{
// just some constructor stuff...
$this->foo = strtoupper($this->foo);
}


/*
* special prefixed magic setters & getters
*/

// this method will be called from __set() when property $what is set
protected function set_what(string $value){
protected function set_what(string $value):void{
$this->what = md5($value);
}

// this method is called on __get() for the property $what
protected function get_what():string{
return 'hash: '.$this->what;
}
}

// from library 2
trait MoreOptions{
protected $bar = 'whatever'; // provide default values
protected string $bar = 'whatever'; // provide default values
}
```

```php
$commonOptions = [
// SomeOptions
'foo' => 'whatever',
'foo' => 'whatever',
// MoreOptions
'bar' => 'nothing',
];

// now plug the several library options together to a single object
// now plug the several library options together to a single object
$container = new class ($commonOptions) extends SettingsContainerAbstract{
use SomeOptions, MoreOptions;
};
Expand All @@ -129,27 +136,31 @@ var_dump($container->foo); // -> WHATEVER (constructor ran strtoupper on the val
var_dump($container->bar); // -> nothing

$container->what = 'some value';
var_dump($container->what); // -> md5 hash of "some value"
var_dump($container->what); // -> hash: 5946210c9e93ae37891dfe96c3e39614 (custom getter added "hash: ")
```

### API

#### [`SettingsContainerAbstract`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerAbstract.php)

method | return | info
-------- | ---- | -----------
`__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set
(protected) `construct()` | void | calls a method with trait name as replacement constructor for each used trait
`__get(string $property)` | mixed | calls `$this->{'get_'.$property}()` if such a method exists
`__set(string $property, $value)` | void | calls `$this->{'set_'.$property}($value)` if such a method exists
`__isset(string $property)` | bool |
`__unset(string $property)` | void |
`__toString()` | string | a JSON string
`toArray()` | array |
`fromIterable(iterable $properties)` | `SettingsContainerInterface` |
`toJSON(int $jsonOptions = null)` | string | accepts [JSON options constants](http://php.net/manual/json.constants.php)
`fromJSON(string $json)` | `SettingsContainerInterface` |
`jsonSerialize()` | mixed | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface
| method | return | info |
|--------------------------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------|
| `__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set |
| (protected) `construct()` | void | calls a method with trait name as replacement constructor for each used trait |
| `__get(string $property)` | mixed | calls `$this->{'get_'.$property}()` if such a method exists |
| `__set(string $property, $value)` | void | calls `$this->{'set_'.$property}($value)` if such a method exists |
| `__isset(string $property)` | bool | |
| `__unset(string $property)` | void | |
| `__toString()` | string | a JSON string |
| `toArray()` | array | |
| `fromIterable(iterable $properties)` | `SettingsContainerInterface` | |
| `toJSON(int $jsonOptions = null)` | string | accepts [JSON options constants](http://php.net/manual/json.constants.php) |
| `fromJSON(string $json)` | `SettingsContainerInterface` | |
| `jsonSerialize()` | mixed | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface |
| `serialize()` | string | implements the [`Serializable`](https://www.php.net/manual/en/serializable.serialize.php) interface |
| `unserialize(string $data)` | void | implements the [`Serializable`](https://www.php.net/manual/en/serializable.unserialize.php) interface |
| `__serialize()` | array | implements the [`Serializable`](https://www.php.net/manual/en/language.oop5.magic.php#object.serialize) interface |
| `__unserialize(array $data)` | void | implements the [`Serializable`](https://www.php.net/manual/en/language.oop5.magic.php#object.unserialize) interface |

## Disclaimer
This might be either an utterly genius or completely stupid idea - you decide. However, i like it and it works.
Expand Down
13 changes: 7 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,25 @@
"ext-json": "*"
},
"require-dev": {
"phan/phan": "^5.4",
"phpmd/phpmd": "^2.13",
"phpmd/phpmd": "^2.15",
"phpstan/phpstan": "^1.11",
"phpstan/phpstan-deprecation-rules": "^1.2",
"phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "^3.8"
"squizlabs/php_codesniffer": "^3.10"
},
"autoload": {
"psr-4": {
"chillerlan\\Settings\\": "src/"
"chillerlan\\Settings\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"chillerlan\\SettingsTest\\": "tests/"
"chillerlan\\SettingsTest\\": "tests"
}
},
"scripts": {
"phpunit": "@php vendor/bin/phpunit",
"phan": "@php vendor/bin/phan"
"phpstan": "@php vendor/bin/phpstan"
},
"config": {
"lock": false,
Expand Down
Loading

0 comments on commit 5553558

Please sign in to comment.