Skip to content
Draft
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
6 changes: 6 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@
return (new PhpCsFixer\Config())
->setRules([
'@Symfony' => true,
'@PHP80Migration' => true,
'@PHP80Migration:risky' => true,

// [Symfony] defaults to `camelCase`, we set it to `snake_case` (phpspec style)
'php_unit_method_casing' => ['case' => 'snake_case'],

// [Symfony] defaults to `['arrays']`, we add `arguments` and `parameters` (PHP 8.0)
'trailing_comma_in_multiline' => ['elements' => ['arrays', 'arguments', 'parameters']],

// [Symfony] defaults to `true`, we set it to `false` for phpspec
'visibility_required' => false,
])
->setRiskyAllowed(true)
->setUsingCache(true)
->setFinder($finder)
;
22 changes: 18 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# CHANGELOG

## 4.0.0: PHP 8.0 requirement

Dropped support for PHP <8.0

New features:

* added `Attribute` model (PHP 8.0 attributes)
* added attributes support to `Objekt`, `Contract`, `Method`, `Property`, `Argument` and `Constant`
* added union type support in `Type` (e.g. `string|int`, `DateTime|null`)
* added `mixed` type hint support in `Type`
* added support for class property types
* added constructor property promotion support (visibility on `Argument`)
* added support for nullable typehints

## 3.0.2: Dockerised dev environment

* setup Github Actions
* changed tooling from scripts to Makefile
* installed phpstan as a dev depdendency
* installed swiss-knife as a dev depdendency
* installed rector as a dev depdendency
* installed phpstan as a dev dependency
* installed swiss-knife as a dev dependency
* installed rector as a dev dependency
* upgraded PHP CS fixer to v2.19.3
* dockerized for local development

Expand Down Expand Up @@ -41,7 +55,7 @@ Normalization from float to double, thanks to @ItsKelsBoys

Added support for PHP 7.2, thanks to @roukmoute

BC break: Object has be renamed to Objekt, has it is a reserved keyword.
BC break: Object has been renamed to Objekt, has it is a reserved keyword.

## 2.0.0: PHP 7 and Return type hints

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ make lib-init

## Standard code

Use [PHP CS fixer](http://cs.sensiolabs.org/) to make your code compliant with
Use [PHP CS Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to make your code compliant with
Memio's coding standards:

```console
Expand Down Expand Up @@ -87,7 +87,7 @@ To keep your fork up-to-date, you should track the upstream (original) one
using the following command:

```console
$ git remote add upstream https://github.com/memio/model.git
git remote add upstream https://github.com/memio/model.git
```

Then get the upstream changes:
Expand All @@ -103,7 +103,7 @@ git rebase main
Finally, publish your changes:

```console
$ git push -f origin <your-branch>
git push -f origin <your-branch>
```

Your pull request will be automatically updated.
78 changes: 39 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ method arguments and even PHPdoc) by constructing "Model" objects.

Install it using [Composer](https://getcomposer.org/download):

composer require memio/model:^3.0
```console
composer require memio/model:^4.0
```

## Example

Let's say we want to describe the following method:
Let's say we want to describe the following constructor:

```php
/**
* @api
*/
public function doSomething(ValueObject $valueObject, int $type = self::TYPE_ONE, bool $option = true);
public function __construct(
private ValueObject $valueObject,
private string|int $type = self::TYPE_ONE,
private ?bool $option = true,
) {
}
```

In order to do so, we'd need to write the following:
Expand All @@ -32,56 +36,53 @@ require __DIR__.'/vendor/autoload.php';

use Memio\Model\Argument;
use Memio\Model\Method;
use Memio\Model\Phpdoc\ApiTag;
use Memio\Model\Phpdoc\MethodPhpdoc;
use Memio\Model\Phpdoc\ParameterTag;

$method = (new Method('doSomething'))
->setPhpdoc((new MethodPhpdoc())
->addParameterTag(new ParameterTag('Vendor\Project\ValueObject', 'valueObject'))
->addParameterTag(new ParameterTag('int', 'type'))
->addParameterTag(new ParameterTag('bool', 'option'))

->addApiTag(new ApiTag())
$method = (new Method('__construct'))
->addArgument((new Argument('Vendor\Project\ValueObject', 'valueObject'))
->makePrivate()
)
->addArgument(new Argument('Vendor\Project\ValueObject', 'valueObject'))
->addArgument((new Argument('int', 'type'))
->addArgument((new Argument('string|int', 'type'))
->makePrivate()
->setDefaultValue('self::TYPE_ONE')
)
->addArgument((new Argument('bool', 'option'))
->addArgument((new Argument('?bool', 'option'))
->makePrivate()
->setDefaultValue('true')
)
;
```

This example showcases constructor property promotion, union types and nullable types.

Usually models aren't described manually like this, they would be built dynamically:

```php
// Let's say we've received the following two parameters:
$methodName = 'doSomething';
$arguments = [new \Vendor\Project\ValueObject(), ValueObject::TYPE_ONE, true];

$method = new Method($methodName);
$phpdoc = (new MethodPhpdoc())->setApiTag(new ApiTag());
$index = 1;
foreach ($arguments as $rawArgument) {
$type = is_object($rawArgument) ? get_class($argument) : gettype($rawArgument);
$name = 'argument'.$index++;
$argument = new Argument($type, $name);

// Let's say we've received the following parameters:
$parameters = [
['type' => 'Vendor\Project\ValueObject', 'name' => 'valueObject'],
['type' => 'string|int', 'name' => 'type', 'default' => 'self::TYPE_ONE'],
['type' => '?bool', 'name' => 'option', 'default' => 'true'],
];

$method = new Method('__construct');
foreach ($parameters as $parameter) {
$argument = (new Argument($parameter['type'], $parameter['name']))
->makePrivate()
;
if (isset($parameter['default'])) {
$argument->setDefaultValue($parameter['default']);
}
$method->addArgument($argument);
$phpdoc->addParameterTag(new ParameterTag($type, $name));
}
$method->setPhpdoc($phpdoc);
```

We can build dynamically the models using a configuration file, user input, existing
source code... Possibilities are endless!
source code, etc. Possibilities are endless!

Once built these models can be further tweaked, and converted to another format:
an array, source code, etc... Again, the possibilities are endless!
Once built, these models can be further tweaked and converted to another format:
an array, source code, etc.

Have a look at [the main respository](http://github.com/memio/memio) to discover the full power of Medio.
Have a look at [the main repository](http://github.com/memio/memio) to discover the full power of Memio.

## Want to know more?

Expand All @@ -98,7 +99,7 @@ make phpspec arg='--format pretty' # Run the specifications
You can see the current and past versions using one of the following:

* the `git tag` command
* the [releases page on Github](https://github.com/memio/memio/releases)
* the [releases page on Github](https://github.com/memio/model/releases)
* the file listing the [changes between versions](CHANGELOG.md)

And finally some meta documentation:
Expand All @@ -113,4 +114,3 @@ And finally some meta documentation:
* extract `Import` (use statement) from `FullyQualifiedName`
* get rid of `FullyQualifiedName`
* support more PHPdoc stuff
* support annotations
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"Memio\\Model\\": "src/Memio/Model"
}},
"require": {
"php": "^7.2 || ^8.0"
"php": "^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.19.3",
"phpspec/phpspec": "^6.1 || ^7.0",
"phpspec/phpspec": "^7.0",
"phpstan/phpstan": "1.12.32",
"rector/rector": "^1.2.10",
"rector/swiss-knife": "^2.3"
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ includes:

parameters:
level: 0
phpVersion: 70200
phpVersion: 80000
paths:
- src/
4 changes: 2 additions & 2 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
return RectorConfig::configure()
->withCache(
'/tmp/rector',
FileCacheStorage::class
FileCacheStorage::class,
)
->withPaths([
__DIR__,
Expand All @@ -23,7 +23,7 @@
])
->withSets([
// —— PHP ——————————————————————————————————————————————————————————————
SetList::PHP_72,
SetList::PHP_80,
])
->withRules([
]);
39 changes: 34 additions & 5 deletions spec/Memio/Model/ArgumentSpec.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* This file is part of the memio/model package.
*
Expand All @@ -11,26 +13,27 @@

namespace spec\Memio\Model;

use Memio\Model\Attribute;
use PhpSpec\ObjectBehavior;

class ArgumentSpec extends ObjectBehavior
{
function let()
function let(): void
{
$this->beConstructedWith('array', 'lines');
}

function it_has_a_type()
function it_has_a_type(): void
{
$this->type->name->shouldBe('array');
}

function it_has_a_name()
function it_has_a_name(): void
{
$this->name->shouldBe('lines');
}

function it_can_have_default_value()
function it_can_have_default_value(): void
{
$this->defaultValue->shouldBe(null);

Expand All @@ -41,7 +44,7 @@ function it_can_have_default_value()
$this->defaultValue->shouldBe(null);
}

function it_can_be_variadic()
function it_can_be_variadic(): void
{
$this->isVariadic()->shouldBe(false);

Expand All @@ -51,4 +54,30 @@ function it_can_be_variadic()
$this->removeVariadic();
$this->isVariadic()->shouldBe(false);
}

function it_can_have_attributes(Attribute $attribute): void
{
$this->attributes->shouldBe([]);
$this->addAttribute($attribute);
$this->attributes->shouldBe([$attribute]);
$this->removeAttributes();
$this->attributes->shouldBe([]);
}

function it_can_have_visibility(): void
{
$this->visibility->shouldBe('');

$this->makePublic();
$this->visibility->shouldBe('public');

$this->makeProtected();
$this->visibility->shouldBe('protected');

$this->makePrivate();
$this->visibility->shouldBe('private');

$this->removeVisibility();
$this->visibility->shouldBe('');
}
}
39 changes: 39 additions & 0 deletions spec/Memio/Model/AttributeSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

/*
* This file is part of the memio/model package.
*
* (c) Loïc Faugeron <faugeron.loic@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace spec\Memio\Model;

use PhpSpec\ObjectBehavior;

class AttributeSpec extends ObjectBehavior
{
const NAME = 'Route';

function let(): void
{
$this->beConstructedWith(self::NAME);
}

function it_has_a_name(): void
{
$this->name->shouldBe(self::NAME);
}

function it_can_have_arguments(): void
{
$this->arguments->shouldBe(null);

$this->setArguments("'/api'");
$this->arguments->shouldBe("'/api'");
}
}
Loading