Skip to content

Commit

Permalink
Merge branch 'next' into develop
Browse files Browse the repository at this point in the history
* next:
  add missing use statement
  update readme
  use ramsey/composer-install
  remove old way to create instances and extract values
  add simple way to extract values from an object
  add simple class to instanciate a new object
  give access to properties attributes
  add ReflectionType and ReflectionProperty
  remove roavs bc check
  use more precise types
  make constructors private
  pass the properties at build time instead of keeping then in memory
  update dependencies
  update psalm
  only use reflection by default to inject/extract properties
  avoid keeping objects in memory
  remove unnecessary annotation
  use CS 2
  change email
  • Loading branch information
Baptouuuu committed Apr 30, 2022
2 parents 4e82b0e + b819e10 commit bb59a0b
Show file tree
Hide file tree
Showing 59 changed files with 880 additions and 3,030 deletions.
71 changes: 13 additions & 58 deletions .github/workflows/ci.yml
Expand Up @@ -3,21 +3,12 @@ name: CI
on: [push, pull_request]

jobs:
roave_bc_check:
name: Roave BC Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: fetch tags
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Roave BC Check
uses: docker://nyholm/roave-bc-check-ga
phpunit:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
php-version: ['7.4', '8.0']
php-version: ['8.1']
name: 'PHPUnit'
steps:
- name: Checkout
Expand All @@ -28,17 +19,8 @@ jobs:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
coverage: none
- name: Get Composer Cache Directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Dependencies
run: composer install --no-progress
- name: Composer
uses: "ramsey/composer-install@v2"
- name: PHPUnit
run: vendor/bin/phpunit
env:
Expand All @@ -48,7 +30,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
php-version: ['7.4', '8.0']
php-version: ['8.1']
name: 'Coverage'
steps:
- name: Checkout
Expand All @@ -59,17 +41,8 @@ jobs:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
coverage: xdebug
- name: Get Composer Cache Directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Dependencies
run: composer install --no-progress
- name: Composer
uses: "ramsey/composer-install@v2"
- name: PHPUnit
run: vendor/bin/phpunit --coverage-clover=coverage.clover
env:
Expand All @@ -81,7 +54,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.4', '8.0']
php-version: ['8.1']
name: 'Psalm'
steps:
- name: Checkout
Expand All @@ -91,24 +64,15 @@ jobs:
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
- name: Get Composer Cache Directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Dependencies
run: composer install --no-progress
- name: Composer
uses: "ramsey/composer-install@v2"
- name: Psalm
run: vendor/bin/psalm --shepherd
cs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.4']
php-version: ['8.1']
name: 'CS'
steps:
- name: Checkout
Expand All @@ -118,16 +82,7 @@ jobs:
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
- name: Get Composer Cache Directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-${{ matrix.php-version }}-composer-
- name: Install Dependencies
run: composer install --no-progress
- name: Composer
uses: "ramsey/composer-install@v2"
- name: CS
run: vendor/bin/php-cs-fixer fix --diff --dry-run --diff-format udiff
run: vendor/bin/php-cs-fixer fix --diff --dry-run
File renamed without changes.
68 changes: 23 additions & 45 deletions README.md
Expand Up @@ -4,67 +4,45 @@
[![codecov](https://codecov.io/gh/innmind/reflection/branch/develop/graph/badge.svg)](https://codecov.io/gh/innmind/reflection)
[![Type Coverage](https://shepherd.dev/github/innmind/reflection/coverage.svg)](https://shepherd.dev/github/innmind/reflection)

Library to build objects and extract data out of them through an immutable API.
Library to build objects and extract data out of them.

## Inject data into an object
## Build and inject data into an object

```php
use Innmind\Reflection\ReflectionObject;
use Innmind\Reflection\Instanciate;
use Innmind\Immutable\{
Map,
Maybe,
};

$refl = ReflectionObject::of($myObject)
->withProperty('foo', 'bar')
->withProperty('bar', 'baz');
$refl->build();
```

This simple code will inject both `foo` and `bar` into your `$myObject` following this strategy:

* look for the setter `setFoo()`
* look for a method `foo()` that has at least one argument
* use reflection to set value directly on the property

**Important**: all strategies using methods will use a camelized version of the property, ie: the property `foo_bar` will lead to `setFooBar()` and `fooBar()`.

## Build a new object

```php
use Innmind\Reflection\ReflectionClass;

class Foo
final class Foo
{
private $foo;
private int $foo;
private mixed $bar;

public function __construct(string $foo)
{
$this->foo = $foo;
}
}

$foo = ReflectionClass::of(Foo::class)
->withProperty('foo', 'bar')
->build();
$object = (new Instanciate)(Foo::class, Map::of(
['foo', 42],
['bar', 'baz'],
)); // Maybe<Foo>
```

The `ReflectionClass` uses the `ReflectionInstanciator` to build the new instance of your class; it's replaceable by any object implementing the `Instanciator` interface and giving it as the fourth argument of `ReflectionClass`.

In case the properties you define to be injected can't be injected through the constructor, it will use internally `ReflectionObject` to do so.
This code will create a new `Foo` object and assign the property `foo` to `42` and `bar` to `'baz'`.

## Extracting data out of an object

```php
use Innmind\Reflection\ReflectionObject;

$properties = ReflectionObject::of($myObject)->extract('foo', 'bar', 'baz');
use Innmind\Reflection\Extract;
use Innmind\Immutable\{
Set,
Maybe,
Map,
};

$properties = (new Extract)($myObject, Set::of('foo', 'bar', 'baz')); // Maybe<Map<non-empty-string, mixed>>
```

Here `$properties` is a collection containing the values of `foo`, `bar` and `baz` that are set in your `$myObject`.

To do so, it uses 3 strategies:

* look for a `getFoo()`
* look for a `foo()` (without required parameters)
* look for a `isFoo()` (without required parameters)
* look for a `hasFoo()` (without required parameters)
* uses reflection to check if the property `foo` exists

**Important**: all strategies using methods will use a camelized version of the property, ie: the property `foo_bar` will lead to `getFooBar()` and `fooBar()`.
11 changes: 6 additions & 5 deletions composer.json
Expand Up @@ -8,15 +8,15 @@
"authors": [
{
"name": "Baptiste Langlade",
"email": "langlade.baptiste@gmail.com"
"email": "baptiste.langlade@hey.com"
}
],
"support": {
"issues": "http://github.com/Innmind/Reflection/issues"
},
"require": {
"php": "~7.4|~8.0",
"innmind/immutable": "~3.0"
"php": "~8.1",
"innmind/immutable": "~4.0"
},
"autoload": {
"psr-4": {
Expand All @@ -31,7 +31,8 @@
},
"require-dev": {
"phpunit/phpunit": "~9.0",
"vimeo/psalm": "~4.4",
"innmind/coding-standard": "^1.1"
"vimeo/psalm": "~4.22",
"innmind/coding-standard": "~2.0",
"innmind/black-box": "^4.18"
}
}
13 changes: 13 additions & 0 deletions fixtures/Attr.php
@@ -0,0 +1,13 @@
<?php
declare(strict_types = 1);

namespace Fixtures\Innmind\Reflection;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class Attr
{
public function __construct(
public string $value,
) {
}
}
43 changes: 0 additions & 43 deletions fixtures/Foo.php

This file was deleted.

38 changes: 38 additions & 0 deletions fixtures/ManyTypes.php
@@ -0,0 +1,38 @@
<?php
declare(strict_types = 1);

namespace Fixtures\Innmind\Reflection;

final class ManyTypes
{
#[Attr('foo')]
private int $a;
#[Attr('bar')]
private float $b;
private string $c;
private bool $d;
private array $e;
private object $f;
private \Closure $g;
private NoConstructor $h;
private mixed $i;
private $j;
private ?NoConstructor $k;
private int|string $union;
private \Countable&\ArrayAccess $intersection;

public function a(): int
{
return $this->a;
}

public function b(): float
{
return $this->b;
}

public function d(): bool
{
return $this->d;
}
}
2 changes: 1 addition & 1 deletion phpunit.xml.dist
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="vendor/autoload.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="vendor/autoload.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" printerClass="Innmind\BlackBox\PHPUnit\ResultPrinterV9">
<coverage>
<include>
<directory>.</directory>
Expand Down
8 changes: 0 additions & 8 deletions src/Exception/Exception.php

This file was deleted.

19 changes: 0 additions & 19 deletions src/Exception/InstanciationFailed.php

This file was deleted.

8 changes: 0 additions & 8 deletions src/Exception/InvalidArgumentException.php

This file was deleted.

0 comments on commit bb59a0b

Please sign in to comment.