Skip to content

Commit 5553558

Browse files
committed
1 parent 394d569 commit 5553558

17 files changed

+260
-173
lines changed

.gitattributes

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
/.build export-ignore
2-
/.github export-ignore
3-
/.phan export-ignore
4-
/.phpdoc export-ignore
5-
/docs export-ignore
6-
/examples export-ignore
7-
/tests export-ignore
8-
/.editorconfig export-ignore
9-
/.gitattributes export-ignore
10-
/.gitignore export-ignore
11-
/.readthedocs.yml export-ignore
12-
/phpcs.xml.dist export-ignore
13-
/phpdoc.xml.dist export-ignore
14-
/phpmd.xml.dist export-ignore
15-
/phpunit.xml.dist export-ignore
1+
/.build export-ignore
2+
/.github export-ignore
3+
/.idea export-ignore
4+
/.phan export-ignore
5+
/.phpdoc export-ignore
6+
/docs export-ignore
7+
/examples export-ignore
8+
/tests export-ignore
9+
/.editorconfig export-ignore
10+
/.gitattributes export-ignore
11+
/.gitignore export-ignore
12+
/.readthedocs.yml export-ignore
13+
/phpcs.xml.dist export-ignore
14+
/phpdoc.xml.dist export-ignore
15+
/phpmd.xml.dist export-ignore
16+
/phpunit.xml.dist export-ignore
17+
/phpstan.dist.neon export-ignore
18+
/phpstan-baseline.neon export-ignore
1619

1720
*.php diff=php

.github/workflows/tests.yml

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
22
# https://github.com/sebastianbergmann/phpunit/blob/master/.github/workflows/ci.yml
33

4+
name: "CI"
5+
46
on:
57
push:
68
branches:
@@ -10,19 +12,17 @@ on:
1012
- v2.x-php7.4
1113

1214

13-
name: "CI"
15+
env:
16+
PHP_EXTENSIONS: json
17+
PHP_INI_VALUES: memory_limit=-1, error_reporting=-1, display_errors=On
18+
1419

1520
jobs:
1621

1722
static-code-analysis:
1823
name: "Static Code Analysis"
19-
2024
runs-on: ubuntu-latest
2125

22-
env:
23-
PHAN_ALLOW_XDEBUG: 0
24-
PHAN_DISABLE_XDEBUG_WARN: 1
25-
2626
strategy:
2727
fail-fast: true
2828
matrix:
@@ -32,24 +32,25 @@ jobs:
3232
- "8.1"
3333
- "8.2"
3434
- "8.3"
35+
# - "8.4"
3536

3637
steps:
3738
- name: "Checkout"
38-
uses: actions/checkout@v3
39+
uses: actions/checkout@v4
3940

4041
- name: "Install PHP"
4142
uses: shivammathur/setup-php@v2
4243
with:
4344
php-version: ${{ matrix.php-version }}
44-
tools: pecl
45+
extensions: ${{ env.PHP_EXTENSIONS }}
46+
ini-values: ${{ env.PHP_INI_VALUES }}
4547
coverage: none
46-
extensions: ast, json
4748

4849
- name: "Update dependencies with composer"
49-
uses: ramsey/composer-install@v2
50+
uses: ramsey/composer-install@v3
5051

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

5455

5556
tests:
@@ -69,26 +70,31 @@ jobs:
6970
- "8.1"
7071
- "8.2"
7172
- "8.3"
73+
# - "8.4"
7274

7375
steps:
7476
- name: "Checkout"
75-
uses: actions/checkout@v3
77+
uses: actions/checkout@v4
7678

7779
- name: "Install PHP with extensions"
7880
uses: shivammathur/setup-php@v2
7981
with:
8082
php-version: ${{ matrix.php-version }}
83+
extensions: ${{ env.PHP_EXTENSIONS }}
84+
ini-values: ${{ env.PHP_INI_VALUES }}
8185
coverage: pcov
82-
extensions: json
8386

8487
- name: "Install dependencies with composer"
85-
uses: ramsey/composer-install@v2
88+
uses: ramsey/composer-install@v3
8689

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

9093
- name: "Send code coverage report to Codecov.io"
91-
uses: codecov/codecov-action@v3
94+
uses: codecov/codecov-action@v4
95+
with:
96+
token: ${{ secrets.CODECOV_TOKEN }}
97+
files: .build/coverage/clover.xml
9298

9399
- name: "Send code coverage report to Codacy"
94100
uses: codacy/codacy-coverage-reporter-action@v1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ phpcs.xml
66
phpdoc.xml
77
phpmd.xml
88
phpunit.xml
9+
phpstan.neon

.phan/config.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

README.md

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -45,31 +45,27 @@ Profit!
4545

4646
## Usage
4747

48-
The `SettingsContainerInterface` (wrapped in`SettingsContainerAbstract` ) provides plug-in functionality for immutable object properties and adds some fancy, like loading/saving JSON, arrays etc.
48+
The `SettingsContainerInterface` (wrapped in`SettingsContainerAbstract`) provides plug-in functionality for immutable object properties and adds some fancy, like loading/saving JSON, arrays etc.
4949
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.
5050

51+
A PHPStan ruleset to exclude errors generated by accessing magic properties on `SettingsContainerInterface` can be found in `rules-magic-access.neon`.
52+
53+
5154
### Simple usage
5255
```php
53-
class MyContainer extends SettingsContainerAbstract{
54-
protected $foo;
55-
protected $bar;
56-
}
57-
```
58-
Typed properties in PHP 7.4+:
59-
```php
6056
class MyContainer extends SettingsContainerAbstract{
6157
protected string $foo;
6258
protected string $bar;
6359
}
6460
```
6561

6662
```php
67-
// use it just like a \stdClass
63+
// use it just like a \stdClass (except the properties are fixed)
6864
$container = new MyContainer;
6965
$container->foo = 'what';
7066
$container->bar = 'foo';
7167

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

9187
### Advanced usage
9288
```php
89+
// from library 1
9390
trait SomeOptions{
94-
protected $foo;
95-
protected $what;
96-
91+
protected string $foo;
92+
protected string $what;
93+
9794
// this method will be called in SettingsContainerAbstract::construct()
9895
// after the properties have been set
99-
protected function SomeOptions(){
96+
protected function SomeOptions():void{
10097
// just some constructor stuff...
10198
$this->foo = strtoupper($this->foo);
10299
}
103-
100+
101+
/*
102+
* special prefixed magic setters & getters
103+
*/
104+
104105
// this method will be called from __set() when property $what is set
105-
protected function set_what(string $value){
106+
protected function set_what(string $value):void{
106107
$this->what = md5($value);
107108
}
109+
110+
// this method is called on __get() for the property $what
111+
protected function get_what():string{
112+
return 'hash: '.$this->what;
113+
}
108114
}
109115

116+
// from library 2
110117
trait MoreOptions{
111-
protected $bar = 'whatever'; // provide default values
118+
protected string $bar = 'whatever'; // provide default values
112119
}
113120
```
114121

115122
```php
116123
$commonOptions = [
117124
// SomeOptions
118-
'foo' => 'whatever',
125+
'foo' => 'whatever',
119126
// MoreOptions
120127
'bar' => 'nothing',
121128
];
122129

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

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

135142
### API
136143

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

139-
method | return | info
140-
-------- | ---- | -----------
141-
`__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set
142-
(protected) `construct()` | void | calls a method with trait name as replacement constructor for each used trait
143-
`__get(string $property)` | mixed | calls `$this->{'get_'.$property}()` if such a method exists
144-
`__set(string $property, $value)` | void | calls `$this->{'set_'.$property}($value)` if such a method exists
145-
`__isset(string $property)` | bool |
146-
`__unset(string $property)` | void |
147-
`__toString()` | string | a JSON string
148-
`toArray()` | array |
149-
`fromIterable(iterable $properties)` | `SettingsContainerInterface` |
150-
`toJSON(int $jsonOptions = null)` | string | accepts [JSON options constants](http://php.net/manual/json.constants.php)
151-
`fromJSON(string $json)` | `SettingsContainerInterface` |
152-
`jsonSerialize()` | mixed | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface
146+
| method | return | info |
147+
|--------------------------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------|
148+
| `__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set |
149+
| (protected) `construct()` | void | calls a method with trait name as replacement constructor for each used trait |
150+
| `__get(string $property)` | mixed | calls `$this->{'get_'.$property}()` if such a method exists |
151+
| `__set(string $property, $value)` | void | calls `$this->{'set_'.$property}($value)` if such a method exists |
152+
| `__isset(string $property)` | bool | |
153+
| `__unset(string $property)` | void | |
154+
| `__toString()` | string | a JSON string |
155+
| `toArray()` | array | |
156+
| `fromIterable(iterable $properties)` | `SettingsContainerInterface` | |
157+
| `toJSON(int $jsonOptions = null)` | string | accepts [JSON options constants](http://php.net/manual/json.constants.php) |
158+
| `fromJSON(string $json)` | `SettingsContainerInterface` | |
159+
| `jsonSerialize()` | mixed | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface |
160+
| `serialize()` | string | implements the [`Serializable`](https://www.php.net/manual/en/serializable.serialize.php) interface |
161+
| `unserialize(string $data)` | void | implements the [`Serializable`](https://www.php.net/manual/en/serializable.unserialize.php) interface |
162+
| `__serialize()` | array | implements the [`Serializable`](https://www.php.net/manual/en/language.oop5.magic.php#object.serialize) interface |
163+
| `__unserialize(array $data)` | void | implements the [`Serializable`](https://www.php.net/manual/en/language.oop5.magic.php#object.unserialize) interface |
153164

154165
## Disclaimer
155166
This might be either an utterly genius or completely stupid idea - you decide. However, i like it and it works.

composer.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,25 @@
2424
"ext-json": "*"
2525
},
2626
"require-dev": {
27-
"phan/phan": "^5.4",
28-
"phpmd/phpmd": "^2.13",
27+
"phpmd/phpmd": "^2.15",
28+
"phpstan/phpstan": "^1.11",
29+
"phpstan/phpstan-deprecation-rules": "^1.2",
2930
"phpunit/phpunit": "^9.6",
30-
"squizlabs/php_codesniffer": "^3.8"
31+
"squizlabs/php_codesniffer": "^3.10"
3132
},
3233
"autoload": {
3334
"psr-4": {
34-
"chillerlan\\Settings\\": "src/"
35+
"chillerlan\\Settings\\": "src"
3536
}
3637
},
3738
"autoload-dev": {
3839
"psr-4": {
39-
"chillerlan\\SettingsTest\\": "tests/"
40+
"chillerlan\\SettingsTest\\": "tests"
4041
}
4142
},
4243
"scripts": {
4344
"phpunit": "@php vendor/bin/phpunit",
44-
"phan": "@php vendor/bin/phan"
45+
"phpstan": "@php vendor/bin/phpstan"
4546
},
4647
"config": {
4748
"lock": false,

0 commit comments

Comments
 (0)