-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
79 changed files
with
3,391 additions
and
641 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,309 @@ | ||
# Bitmasks | ||
|
||
````php | ||
enum Permission { | ||
use Henzeb\Enumhancer\Concerns\Bitmasks; | ||
|
||
case Create; | ||
case Read; | ||
case Update; | ||
case Delete; | ||
} | ||
|
||
Permission::Create->bit(); // returns 1 | ||
Permission::Read->bit(); // returns 2 | ||
Permission::Update->bit(); // returns 4 | ||
Permission::Delete->bit(); // returns 8 | ||
```` | ||
|
||
## Integer backed enums | ||
|
||
Enumhancer allows you to use your own bit values by using an integer or | ||
string backed enum. This is disabled by default. You can enable it by | ||
adding a constant called `BIT_VALUES` that returns true. | ||
|
||
````php | ||
enum PermissionInt: int | ||
{ | ||
use Henzeb\Enumhancer\Concerns\Bitmasks; | ||
|
||
private const BIT_VALUES = true; | ||
|
||
case Create = 8; | ||
case Read = 16; | ||
case Update = 32; | ||
case Delete = 128; | ||
} | ||
|
||
PermissionInt::Create->bit(); // returns 8 | ||
PermissionInt::Read->bit(); // returns 16 | ||
PermissionInt::Update->bit(); // returns 32 | ||
PermissionInt::Delete->bit(); // returns 128 | ||
```` | ||
|
||
Note: when the flag `BIT_VALUES` is set, each case must have a valid bit set. | ||
For example: `7` would throw a fatal error as this consists of the bits `1` `2` | ||
and `4`. | ||
|
||
## Bits | ||
|
||
When you want to use the bits in a dropdown, you can easily use `bits`. | ||
|
||
````php | ||
// returns [1 => 'Create', 2 => 'Read', 4 => 'Update', 8 => 'Delete'] | ||
Permission::bits(); | ||
|
||
// returns [8 => 'Create', 16 => 'Read', 32 => 'Update', 128 => 'Delete'] | ||
PermissionInt::bits(); | ||
|
||
```` | ||
|
||
Note: Just like [Dropdown](dropdown.md), `bits` uses [Labels](labels.md) where applicable. | ||
|
||
## Create bitmasks | ||
|
||
Enumhancer gives you easy tools to work with bitmasks. Just like everywhere else, | ||
if [Mappers](mappers.md) are being used, any value will be mapped. | ||
|
||
### mask | ||
|
||
To get a mask, simply call the static method on your enum. just like with | ||
[Comparison](comparison.md), you can add as many enum or values that represent enums | ||
as you need. | ||
|
||
````php | ||
Permission::mask(); // returns a Bitmask object with value 0 | ||
Permission::mask(Permission::Create); // returns Bitmask with value 1 | ||
Permission::mask(Permission::Create, 'update'); // returns Bitmask with value 5 | ||
Permission::mask(Permission::Create, 'modify'); // throws error | ||
```` | ||
|
||
### fromMask | ||
|
||
To transform a numeric bitmask, retreived from for example a database, | ||
into a `Bitmask` object, you can use `fromMask`. | ||
|
||
````php | ||
Permission::fromMask(0); // returns a Bitmask object with value 0 | ||
Permission::fromMask(1); // returns Bitmask with value 1 | ||
Permission::fromMask(5); // returns Bitmask with value 5 | ||
Permission::fromMask(16); // throws error | ||
|
||
PermissionInt::fromMask(32); // returns a Bitmask object with value 32 | ||
PermissionInt::fromMask(64); // throws error | ||
```` | ||
|
||
numeric bitmasks are validated and can only represent any existing combination | ||
of bits corresponding to existing cases. | ||
|
||
### tryMask | ||
|
||
This method works the same as `fromMask`, but will return a `Bitmask` | ||
with a value of 0 or a specified bitmask instead if an invalid | ||
bitmask is given. | ||
|
||
````php | ||
Permission::tryMask(null); // returns a Bitmask object with value 0 | ||
Permission::tryMask( | ||
null, | ||
Permission::Read | ||
); // returns a Bitmask object with value 1 | ||
Permission::tryMask(0); // returns a Bitmask object with value 0 | ||
Permission::tryMask( | ||
0, | ||
Permission::Read | ||
); // returns a Bitmask object with value 0 | ||
|
||
Permission::tryMask(1); // returns Bitmask with value 1 | ||
Permission::tryMask(5); // returns Bitmask with value 5 | ||
Permission::tryMask(16); // returns a Bitmask object with value 0 | ||
Permission::tryMask(16, 'read'); // returns a Bitmask object with value 1 | ||
|
||
Permission::tryMask( | ||
16, | ||
Permission::Read | ||
); // returns a Bitmask object with value 1 | ||
Permission::tryMask( | ||
16, | ||
Permission::mask('Read', 'Update') | ||
); // returns a Bitmask object with value 3 | ||
|
||
PermissionInt::tryMask(32); // returns a Bitmask object with value 32 | ||
PermissionInt::tryMask(64); // returns a Bitmask object with value 0 | ||
PermissionInt::tryMask( | ||
64, | ||
'Read', 'Update' | ||
); // returns a Bitmask object with value 3 | ||
```` | ||
|
||
Note: If [Defaults](defaults.md) is configured, tryMask will use that default. | ||
You can counteract by passing a null as the second value. | ||
|
||
## Bitmask operations | ||
|
||
The `Bitmask` object operates a similar to a `Flag Bag` you see in other libraries. | ||
You can easily modify and validate. It is however tied to the enum that created it. | ||
|
||
The `Bitmask` object is also implementing a fluent interface for all methods, unless | ||
specified otherwise. | ||
|
||
All the methods accept either enums or strings or integers representing | ||
the enums either mapped or directly. You can also insert Bitmask instances | ||
as (one of) it's argument, as long as the Bitmask belongs to the same enum. | ||
|
||
### Value | ||
|
||
````php | ||
Permission::mask()->value(); // returns 0 | ||
Permission::mask('Read')->value(); // returns 2 | ||
Permission::mask('Create', 'Read')->value(); // returns 3 | ||
```` | ||
|
||
#### Stringable | ||
|
||
Bitmask objects are stringable. It will return the value as a string | ||
|
||
````php | ||
(string)Permission::mask(); // returns "0" | ||
(string)Permission::mask('Read'); // returns "2" | ||
(string)Permission::mask('Create', 'Read'); // returns "3" | ||
```` | ||
|
||
### Cases | ||
|
||
Returns an array of cases corresponding to the bits set. | ||
|
||
````php | ||
Permission::mask()->cases(); // returns [] | ||
Permission::mask('Read')->cases(); // returns [Permission::Read] | ||
Permission::mask('Create', 'Read')->cases(); // returns [Permission::Create, Permission::Read] | ||
```` | ||
|
||
### Set | ||
|
||
````php | ||
Permission::mask()->set(Permission::Read); // sets value to 2 | ||
Permission::mask('Read')->set(Permission::Create); // sets value to 3 | ||
Permission::mask('Read') | ||
->set(Permission::mask(Permission::Create)); // sets value to 3 | ||
Permission::mask('Read')->set(Permission::Create, 'Update'); // sets value to 7 | ||
Permission::mask('Read')->set(Permission::Read); // keeps value as 2 | ||
```` | ||
|
||
### Unset | ||
|
||
````php | ||
Permission::mask()->unset(Permission::Read); // keeps value as 0 | ||
Permission::mask('Read')->unset(Permission::Read); // sets value to 0 | ||
Permission::mask('Read') | ||
->unset(Permission::mask(Permission::Read)); // sets value to 0 | ||
Permission::mask('Read', 'Update') | ||
->unset(Permission::Create, 'Update'); // sets value to 2 | ||
Permission::mask('Read')->unset(Permission::Read); // keeps value as 2 | ||
```` | ||
|
||
### Toggle | ||
|
||
Toggle toggles between 0 and 1. If a bit is set, it wil unset it and vice versa. | ||
You can mix up as many as you like, it will toggle each value individually. | ||
|
||
````php | ||
Permission::mask()->toggle(Permission::Read); // sets value to 1 | ||
Permission::mask('Read')->toggle(Permission::Read); // sets value to 0 | ||
Permission::mask() | ||
->toggle(Permission::mask(Permission::Read)); // sets value to 1 | ||
Permission::mask('Read', 'Update') | ||
->toggle(Permission::Create, 'Update'); // sets value to 3 | ||
Permission::mask('Update')->toggle(Permission::Read); // sets value to 6 | ||
```` | ||
|
||
### Clear | ||
|
||
Resets the value to 0. This means no bits are set after calling it. | ||
|
||
````php | ||
Permission::mask()->clear(); // sets value to 0 | ||
Permission::mask('Read')->clear(); // sets value to 0 | ||
Permission::mask('Read', 'Update')->clear(); // sets value to 0 | ||
```` | ||
|
||
### Copy | ||
|
||
Copy allows you to duplicate the `Bitmask`. It creates a whole new instance, | ||
with the current value, you can modify, without modifying the original one. | ||
|
||
````php | ||
Permission::mask()->copy(); // returns new Bitmask instance. | ||
```` | ||
|
||
### Has | ||
|
||
````php | ||
Permission::mask()->has('Read'); // returns false | ||
Permission::mask('Read')->has(Permission::Read); // returns true | ||
Permission::mask('Create')->has('Read'); // returns false | ||
```` | ||
|
||
### All | ||
|
||
````php | ||
Permission::mask()->all(); // returns true | ||
Permission::mask()->all('Read', 'Create'); // returns false | ||
Permission::mask('Read')->all('Read', 'Create'); // returns false | ||
Permission::mask('Read', 'Update', 'Delete')->all('Read', 'Update'); // returns true | ||
```` | ||
|
||
### Any | ||
|
||
````php | ||
Permission::mask()->all(); // returns true | ||
Permission::mask()->all('Read', 'Create'); // returns false | ||
Permission::mask('Read')->all('Read', 'Create'); // returns false | ||
Permission::mask('Read', 'Update', 'Delete')->all('Read', 'Update'); // returns true | ||
```` | ||
|
||
### Xor | ||
|
||
````php | ||
Permission::mask()->xor(); // returns false | ||
Permission::mask()->xor('Read', 'Create'); // returns false | ||
Permission::mask('Read')->xor('Read', 'Create'); // returns true | ||
Permission::mask('Read', 'Update')->xor('Read', 'Update'); // returns false | ||
```` | ||
|
||
### None | ||
|
||
````php | ||
Permission::mask()->none(); // returns true | ||
Permission::mask()->none('Read', 'Create'); // returns true | ||
Permission::mask('Read')->none('Read', 'Create'); // returns false | ||
Permission::mask('Read', 'Update')->none('Delete', 'Create'); // returns true | ||
```` | ||
|
||
### for | ||
|
||
Bitmask does it for you, but if you want to check up front, you can check if | ||
the Bitmask belongs to a certain enum. | ||
|
||
````php | ||
Permission::mask()->for(Permission::class); // returns true | ||
Permission::mask()->for(PermissionInt::class); // returns false | ||
```` | ||
|
||
### forOrFail | ||
|
||
Does the same as `for`, but instead throws an exception when it does not match. | ||
|
||
````php | ||
Permission::mask()->for(Permission::class); // returns true | ||
Permission::mask()->for(PermissionInt::class); // throws exception | ||
```` | ||
|
||
### ForEnum | ||
|
||
Returns the class name of the enum the Bitmask belongs to. | ||
|
||
````php | ||
Permission::mask()->forEnum(); // returns Permission::class | ||
PermissionInt::mask()->forEnum(); // returns PermissionInt::class | ||
```` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.