Skip to content

Commit def9274

Browse files
author
Kevin Buchholz
committed
Merge branch 'release/2.0.0'
2 parents f5bb80d + 8804197 commit def9274

37 files changed

+508
-332
lines changed

.travis.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
language: php
22

33
php:
4-
- 7.1
5-
- 7.2
64
- 7.3
7-
- 7.4snapshot
5+
- 7.4
86
- nightly
97

108
matrix:
119
include:
12-
- php: 7.1
10+
- php: 7.3
1311
env: COMPOSER_FLAGS="--prefer-lowest"
14-
- php: 7.2
12+
- php: 7.4
1513
env: COMPOSER_FLAGS="--prefer-lowest"
14+
- php: 7.4
1615
allow_failures:
17-
- php: 7.4snapshot
1816
- php: nightly
1917

2018
before_script:

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
## Next release
44

55

6+
## 2.0.0 - 2020-03-29 - major release
7+
8+
### Added
9+
- Laravel 7.x support
10+
- Laravel 7 custom casts
11+
- `Configurable`-trait for enums
12+
13+
### Changed
14+
- Dropped Support for version of Laravel lower than 7.0
15+
- Dropped Support for versions of PHP lower than 7.3
16+
- Removed `HasEnums`-trait in favor of custom casts
17+
- Removed possibility to set weight path by static property to prevent notices when accessing undefined properties
18+
19+
620
## 1.3.0 - 2019-08-31 - minor release
721

822
### Added

README.md

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,22 @@ Enum implementation for Laravel. Based on [eloquent/enumeration](https://github.
2727
* [Methods](#methods)
2828
* [Validation](#validation)
2929
* [Localization](#localization)
30-
* [Model Trait](#model-trait)
30+
* [Custom cast](#custom-cast)
3131
* [Weighted Enums](#weighted-enums)
3232
* [License information](#license-information)
3333

3434
## Requirements
3535

3636
* eloquent/enumeration 6.0 or newer
37-
* Laravel 5.7 or newer;
38-
* PHP 7.1 or newer
37+
* Laravel 7 or newer;
38+
* PHP 7.3 or newer
3939

4040
## Install
4141

4242
Via Composer
4343

4444
``` bash
45-
46-
$ composer require sourceboat/laravel-enumeration
47-
```
48-
49-
If you're using Laravel < 5.5 you'll need to add the service provider to `config/app.php`
50-
51-
``` php
52-
'Sourceboat\Enumeration\EnumerationServiceProvider'
45+
composer require sourceboat/laravel-enumeration
5346
```
5447

5548
## Generating enums
@@ -269,11 +262,9 @@ return [
269262
];
270263
```
271264

272-
## Model Trait
273-
274-
You can use the `HasEnums` trait to enable automatic casting of properties to enums. When used, it also automatically checks if a value set to an enum property is valid, if not it throws an `UndefinedMemberException`.
265+
## Custom Cast
275266

276-
To enable this functionality you will have to use the trait and set the enums property on your model.
267+
You can use the `Enum` custom cast to enable automatic casting of properties to enums. When used, it will set the property to the default members value when set to an invalid value, same goes when the initial value is invalid when getting it, it will return the default member.
277268

278269
```php
279270
<?php
@@ -282,19 +273,17 @@ namespace App\Models;
282273

283274
use App\Enums\UserType;
284275
use Illuminate\Database\Eloquent\Model;
285-
use Sourceboat\Enumeration\Traits\HasEnums;
276+
use Sourceboat\Enumeration\Casts\Enum;
286277

287278
class User extends Model
288279
{
289-
use HasEnums;
290-
291-
protected $enums = [
292-
'type' => UserType::class,
280+
protected $casts = [
281+
'type' => Enums::class . ':' . UserType::class,
293282
];
294283
}
295284
```
296285

297-
The enums property is a simple mapping of model attributes to enum classes. For cases where you want an attribute to be nullable, but don't want to have a `null`-value member in your enum, you can specify this explicitly:
286+
By default the custom cast treats the property as nullable, meaning that the property can be set to null and also return it, instead of an enum member, this can the disabled on an per property basis:
298287

299288
```php
300289
<?php
@@ -303,16 +292,14 @@ namespace App\Models;
303292

304293
use App\Enums\UserType;
305294
use Illuminate\Database\Eloquent\Model;
306-
use Sourceboat\Enumeration\Traits\HasEnums;
295+
use Sourceboat\Enumeration\Casts\Enum;
307296

308297
class User extends Model
309298
{
310-
use HasEnums;
311-
312-
protected $enums = [
313-
'type' => [ 'nullable' => true, 'enum' => UserType::class ],
314-
];
315-
}
299+
protected $casts = [
300+
'type' => Enums::class . ':' . UserType::class . ',0', // appending the 0 means it is not nullable,
301+
]; // this seems counter intuitive, but thats the way it is recognized as `false`,
302+
} // as `false` is somehow evaluated as `true`.
316303
```
317304

318305
If the casted attribute is not set to be nullable and/or has a value not represented by the enum, you will get the default member of the enum when accessing the attribute.
@@ -329,7 +316,7 @@ echo $type->value; // "0"
329316

330317
## Weighted Enums
331318

332-
It is Possible to define weights for enum members. the standard way is to define the weights a config file and them implement the `Weighted`-interface with the `IsWeighted`-trait and define the path to your config. The weigths can be defined as integer or float values.
319+
It is Possible to define weights for enum members. the standard way is to define the weights a config file and them implement the `Weighted`-interface with the `IsWeighted`-trait and define the path to your config. The weights can be defined as integer or float values.
333320

334321
``` php
335322
// The Enum
@@ -355,8 +342,6 @@ final class UserType extends Enumeration implements Weighted
355342
const Moderator = 1;
356343
const Subscriber = 2;
357344
const SuperAdministrator = 3;
358-
359-
protected static $weightOptionsKey = 'test'; // optional, by standard its `sprintf('enums.%s.weights', static::class)`
360345
}
361346
```
362347

@@ -399,6 +384,70 @@ Available scopes:
399384
* `whereBetweenEnum(string $attribute, Weighted $lowerMember, Weighted $higherMember)`
400385
* `whereBetweenOrEqualEnum(string $attribute, Weighted $lowerMember, Weighted $higherMember)`
401386

387+
388+
## Configurable Enums
389+
390+
It is possible to define config values for enums and access them without defining the whole path, but a logical part of it.
391+
The default path for the configuration is: `enums.<enum class>.<given key>.<enum value>`
392+
393+
For example:
394+
395+
``` php
396+
// The Enum
397+
<?php
398+
399+
namespace App\Enums;
400+
401+
use Sourceboat\Enumeration\Enumeration;
402+
use Sourceboat\Enumeration\Enums\Interfaces\Configurable;
403+
use Sourceboat\Enumeration\Enums\Traits\IsConfigurable;
404+
405+
/**
406+
* @method static \App\Enums\UserType Administrator()
407+
* @method static \App\Enums\UserType Moderator()
408+
* @method static \App\Enums\UserType Subscriber()
409+
* @method static \App\Enums\UserType SuperAdministrator()
410+
*/
411+
final class UserType extends Enumeration implements Configurable
412+
{
413+
use IsConfigurable;
414+
415+
const Administrator = 0;
416+
const Moderator = 1;
417+
const Subscriber = 2;
418+
const SuperAdministrator = 3;
419+
}
420+
```
421+
422+
``` php
423+
// enums.php
424+
<?php
425+
use App\Enums\UserType;
426+
427+
return [
428+
UserType::class => [
429+
'permissions' => [
430+
UserType::Administrator => [
431+
'user.foreign.edit',
432+
'user.foreign.delete',
433+
],
434+
UserType::Subscriber => [
435+
'user.self.edit',
436+
'user.self.delete',
437+
],
438+
]
439+
]
440+
]
441+
```
442+
443+
then you can access these values by:
444+
445+
``` php
446+
UserType::Subscriber()->config('permissions'); // which return the given array.
447+
UserType::Moderator()->config('permissions', ['thread.foreign.archive']); // you can also define a default value.
448+
```
449+
450+
402451
## License information
403452

404453
Much of the functionality in this Package is inspired by [bensampo/laravel-enum](https://github.com/bensampo/laravel-enum) and some code has been taken from it and modified, for example the `MakeEnumCommand.php`, the `EnumServiceProvider.php` and this readme.

composer.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,19 @@
2424
}
2525
],
2626
"require": {
27-
"php": ">=7.1",
27+
"php": ">=7.3",
2828
"eloquent/enumeration": "^6.0",
29-
"laravel/framework": "5.7.* || 5.8.* || ^6.0"
29+
"illuminate/console": ">=7.0",
30+
"illuminate/contracts": ">=7.0",
31+
"illuminate/support": ">=7.0"
3032
},
3133
"require-dev": {
32-
"consistence/coding-standard": "3.7",
33-
"orchestra/testbench": "~3.0 || 4.*",
34+
"consistence/coding-standard": "3.10",
35+
"orchestra/testbench": "^5.0",
3436
"phpmd/phpmd": "^2.6",
35-
"phpunit/phpunit": "7.4.* || 8.3.* || 8.4.* || 8.5.*",
36-
"slevomat/coding-standard": "4.8.7",
37-
"squizlabs/php_codesniffer": "^3.4"
37+
"phpunit/phpunit": "8.3.* || 8.4.* || 8.5.* || 9.0.*",
38+
"slevomat/coding-standard": "6.0.8",
39+
"squizlabs/php_codesniffer": "^3.5"
3840
},
3941
"autoload": {
4042
"psr-4": {

phpcs.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword.NonFullyQualifiedExtends"/>
3535
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword.NonFullyQualifiedUse"/>
3636
<exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.PartialUse"/>
37-
<exclude name="SlevomatCodingStandard.Types.EmptyLinesAroundTypeBraces"/>
3837
<exclude name="SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing" />
3938
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversablePropertyTypeHintSpecification"/>
4039
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification"/>
@@ -47,6 +46,9 @@
4746
<exclude name="SlevomatCodingStandard.ControlStructures.ControlStructureSpacing.IncorrectLinesCountAfterControlStructure"/>
4847
<exclude name="SlevomatCodingStandard.ControlStructures.DisallowShortTernaryOperator.DisallowedShortTernaryOperator"/>
4948
<exclude name="SlevomatCodingStandard.Operators.DisallowIncrementAndDecrementOperators.DisallowedPostIncrementOperator"/>
49+
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint"/>
50+
<exclude name="SlevomatCodingStandard.TypeHints.DisallowMixedTypeHint"/>
51+
<exclude name="SlevomatCodingStandard.Functions.RequireArrowFunction"/>
5052
</rule>
5153

5254
<!-- exclude directories from certain rules -->
@@ -57,7 +59,11 @@
5759
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
5860
<exclude-pattern>*/database/*</exclude-pattern>
5961
</rule>
60-
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingPropertyTypeHint">
61-
<exclude-pattern>*/tests/*</exclude-pattern>
62+
63+
<rule ref="SlevomatCodingStandard.Classes.EmptyLinesAroundClassBraces">
64+
<properties>
65+
<property name="linesCountAfterOpeningBrace" value="0" />
66+
<property name="linesCountBeforeClosingBrace" value="0" />
67+
</properties>
6268
</rule>
6369
</ruleset>

phpmd.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<description>The coding standard for this project.</description>
44
<rule ref="rulesets/cleancode.xml">
55
<exclude name="StaticAccess" />
6+
<exclude name="BooleanArgumentFlag" />
67
</rule>
78
<rule ref="rulesets/codesize.xml" />
89
<rule ref="rulesets/controversial.xml" />

src/Casts/Enum.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace Sourceboat\Enumeration\Casts;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
7+
class Enum implements CastsAttributes
8+
{
9+
private $enumClass;
10+
11+
private $nullable;
12+
13+
public function __construct(string $enumClass, bool $nullable = true)
14+
{
15+
$this->enumClass = $enumClass;
16+
$this->nullable = $nullable;
17+
}
18+
19+
/**
20+
* Transform the attribute from the underlying model values.
21+
*
22+
* @param \Illuminate\Database\Eloquent\Model $model
23+
* @param string $key
24+
* @param mixed $value
25+
* @param array<mixed> $attributes
26+
* @return self|null
27+
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
28+
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
29+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
30+
*/
31+
public function get($model, string $key, $value, array $attributes)
32+
{
33+
if ($this->enumClass::hasValue($value)) {
34+
return $this->enumClass::memberByValue($value);
35+
}
36+
37+
if ($this->nullable && is_null($value)) {
38+
return $value;
39+
}
40+
41+
return $this->enumClass::defaultMember();
42+
}
43+
44+
/**
45+
* Transform the attribute to its underlying model values.
46+
*
47+
* @param \Illuminate\Database\Eloquent\Model $model
48+
* @param string $key
49+
* @param mixed $value
50+
* @param array<mixed> $attributes
51+
* @return array<mixed>
52+
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
53+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
54+
*/
55+
public function set($model, string $key, $value, array $attributes): array
56+
{
57+
if ($this->enumClass::hasValue($value)
58+
|| ($this->nullable && is_null($value))) {
59+
return [
60+
$key => $value,
61+
];
62+
}
63+
64+
if ($value instanceof $this->enumClass) {
65+
return [
66+
$key => $value->value(),
67+
];
68+
}
69+
70+
return [
71+
$key => $this->enumClass::defaultMember()->value(),
72+
];
73+
}
74+
}

0 commit comments

Comments
 (0)