Skip to content

Commit 5242874

Browse files
committed
Add more usage docs
1 parent a3eac90 commit 5242874

File tree

2 files changed

+347
-5
lines changed

2 files changed

+347
-5
lines changed

README.md

+346-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# PHP Enum
22

3+
![Tests](https://github.com/ekvedaras/php-enum/workflows/run-tests/badge.svg)
34
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE)
45
[![Latest Version on Packagist](https://img.shields.io/packagist/v/ekvedaras/php-enum.svg?style=flat)](https://packagist.org/packages/ekvedaras/php-enum)
56
[![Total Downloads](https://img.shields.io/packagist/dt/ekvedaras/php-enum.svg?style=flat)](https://packagist.org/packages/ekvedaras/php-enum)
6-
![Tests](https://github.com/ekvedaras/php-enum/workflows/run-tests/badge.svg)
77

8-
Original idea taken from [happy-types/enumerable-type](https://packagist.org/packages/happy-types/enumerable-type), so take a look, it may suit your needs better.
8+
![Twitter Follow](https://img.shields.io/twitter/follow/ekvedaras?style=plastic)
9+
10+
Big thanks [happy-types/enumerable-type](https://packagist.org/packages/happy-types/enumerable-type) for the original idea. Take a look if it suits your needs better.
11+
912
This package adds `meta` field, provides a few more methods like `options`, `keys`, `json`, etc.
1013
and there are `array` and illuminate `collection` implementations to choose from.
1114

@@ -15,9 +18,10 @@ and there are `array` and illuminate `collection` implementations to choose from
1518
* By type hinting forces only allowed values to be passed to methods (or returned)
1619
* Easy way to list all possible values
1720
* More feature rich and flexible then other enum implementations
21+
* Works with strict (`===`) operator
1822
* IDE friendly, so auto complete, usage analysis and refactorings all work
1923

20-
## Usage
24+
## Defining enums
2125

2226
Create enums by extending either `EKvedaras\PHPEnum\PHPArray\Enum` or `EKvedaras\PHPEnum\Illuminate\Collection\Enum`.
2327

@@ -26,7 +30,8 @@ Create enums by extending either `EKvedaras\PHPEnum\PHPArray\Enum` or `EKvedaras
2630

2731
use EKvedaras\PHPEnum\PHPArray\Enum;
2832

29-
class PaymentStatus extends Enum {
33+
class PaymentStatus extends Enum
34+
{
3035
/**
3136
* @return static
3237
*/
@@ -52,3 +57,340 @@ class PaymentStatus extends Enum {
5257
}
5358
}
5459
```
60+
61+
Integers can be used as IDs instead of string values if you prefer.
62+
63+
## Usage
64+
65+
### Retrieving and comparing enum values
66+
67+
```php
68+
// Retrieving value statically
69+
$status1 = PaymentStatus::completed();
70+
71+
// Retrieving value dynamically from ID
72+
$status2 = PaymentStatus::from('completed');
73+
74+
// Strict comparison is supported
75+
var_dump($status1 === $status2); // true
76+
```
77+
78+
### Accessing value properties
79+
80+
```php
81+
$status = PaymentStatus::copmleted();
82+
83+
$status->id(); // 'completed'
84+
$status->name(); // 'Payment has been processed'
85+
$status->meta(); // null
86+
```
87+
88+
### Listing enum values
89+
90+
There are two implementations provided:
91+
92+
#### PHP array
93+
94+
To use PHP array your enums should extend `EKvedaras\PHPEnum\PHPArray\Enum` class
95+
96+
```php
97+
var_dump(PaymentStatus::enum());
98+
/*
99+
array(3) {
100+
'pending' =>
101+
class PaymentStatus#12 (3) {
102+
protected $id =>
103+
string(7) "pending"
104+
protected $name =>
105+
string(18) "Payment is pending"
106+
protected $meta =>
107+
NULL
108+
}
109+
'completed' =>
110+
class PaymentStatus#363 (3) {
111+
protected $id =>
112+
string(9) "completed"
113+
protected $name =>
114+
string(26) "Payment has been processed"
115+
protected $meta =>
116+
NULL
117+
}
118+
'failed' =>
119+
class PaymentStatus#13 (3) {
120+
protected $id =>
121+
string(6) "failed"
122+
protected $name =>
123+
string(18) "Payment has failed"
124+
protected $meta =>
125+
NULL
126+
}
127+
}
128+
*/
129+
```
130+
131+
```php
132+
var_dump(PaymentStatus::options());
133+
/*
134+
array(3) {
135+
'pending' =>
136+
string(18) "Payment is pending"
137+
'completed' =>
138+
string(26) "Payment has been processed"
139+
'failed' =>
140+
string(18) "Payment has failed"
141+
}
142+
*/
143+
```
144+
145+
```php
146+
var_dump(PaymentStatus::keys());
147+
/*
148+
array(3) {
149+
[0] =>
150+
string(7) "pending"
151+
[1] =>
152+
string(9) "completed"
153+
[2] =>
154+
string(6) "failed"
155+
}
156+
*/
157+
```
158+
159+
```php
160+
var_dump(PaymentStatus::json()); // Will include meta if defined
161+
```
162+
```json
163+
{
164+
"pending": {
165+
"id": "pending",
166+
"name": "Payment is pending"
167+
},
168+
"completed": {
169+
"id": "completed",
170+
"name": "Payment has been processed"
171+
},
172+
"failed": {
173+
"id": "failed",
174+
"name": "Payment has failed"
175+
}
176+
}
177+
```
178+
179+
```php
180+
var_dump(PaymentStatus::jsonOptions());
181+
```
182+
```json
183+
{
184+
"pending": "Payment is pending",
185+
"completed": "Payment has been processed",
186+
"failed": "Payment has failed"
187+
}
188+
```
189+
190+
#### Illuminate Collection
191+
192+
**Either `illuminate/support` or `illuminate/collections` package is required which is not installed by default.**
193+
194+
To use Illuminate Collection your enums should extend `EKvedaras\PHPEnum\Illuminate\Collection\Enum` class.
195+
196+
The only difference is `enum`, `options` and `keys` methods will return `Collection` instances instead of arrays.
197+
The rest works exactly the same.
198+
199+
```php
200+
var_dump(PaymentStatus::enum());
201+
/*
202+
class Illuminate\Support\Collection#362 (1) {
203+
protected $items =>
204+
array(3) {
205+
'pending' =>
206+
class PaymentStatus#12 (3) {
207+
protected $id =>
208+
string(7) "pending"
209+
protected $name =>
210+
string(18) "Payment is pending"
211+
protected $meta =>
212+
NULL
213+
}
214+
'completed' =>
215+
class PaymentStatus#363 (3) {
216+
protected $id =>
217+
string(9) "completed"
218+
protected $name =>
219+
string(26) "Payment has been processed"
220+
protected $meta =>
221+
NULL
222+
}
223+
'failed' =>
224+
class PaymentStatus#13 (3) {
225+
protected $id =>
226+
string(6) "failed"
227+
protected $name =>
228+
string(18) "Payment has failed"
229+
protected $meta =>
230+
NULL
231+
}
232+
}
233+
}
234+
*/
235+
```
236+
237+
```php
238+
var_dump(PaymentStatus::options());
239+
/*
240+
class Illuminate\Support\Collection#368 (1) {
241+
protected $items =>
242+
array(3) {
243+
'pending' =>
244+
string(18) "Payment is pending"
245+
'completed' =>
246+
string(26) "Payment has been processed"
247+
'failed' =>
248+
string(18) "Payment has failed"
249+
}
250+
}
251+
*/
252+
```
253+
254+
```php
255+
var_dump(PaymentStatus::keys());
256+
/*
257+
class Illuminate\Support\Collection#13 (1) {
258+
protected $items =>
259+
array(3) {
260+
[0] =>
261+
string(7) "pending"
262+
[1] =>
263+
string(9) "completed"
264+
[2] =>
265+
string(6) "failed"
266+
}
267+
}
268+
*/
269+
```
270+
271+
### Meta
272+
273+
Meta field is intentionally left as mixed type as it could be used for various reasons.
274+
For example linking enum options with a specific implementation:
275+
276+
```php
277+
<?php
278+
279+
use EKvedaras\PHPEnum\PHPArray\Enum;
280+
281+
class PaymentMethod extends Enum
282+
{
283+
final public static function payPal(): self
284+
{
285+
return static::get('paypal', 'PayPal', PayPalHandler::class);
286+
}
287+
288+
final public static function stripe(): self
289+
{
290+
return static::get('stripe', 'Stripe', StripeHandler::class);
291+
}
292+
}
293+
```
294+
295+
Resolving payment handler in Laravel:
296+
297+
```php
298+
$method = PaymentMethod::from($request['method_id']);
299+
300+
$handler = app($method->meta());
301+
```
302+
303+
Meta could also be used as a more in detail description of each option that could be displayed to users
304+
or some other object linking other classes, resources together.
305+
306+
Furthermore, in some cases it is useful to resolve enum option from meta. That is also possible:
307+
```php
308+
$method = PaymentMethod::from(StripeHandler::class);
309+
```
310+
311+
## Things to know
312+
313+
### `final public static function`
314+
315+
Only methods marked as `final public static` will be considered as possible values of enum. Other methods are still there, but
316+
they will not be returned in `enum` / `keys` / `options`, etc. results and won't be considered as valid values. However, this allows
317+
to extend enums and make them more useful. For example:
318+
319+
```php
320+
<?php
321+
322+
use EKvedaras\PHPEnum\Illuminate\Collection\Enum;
323+
use Illuminate\Support\Collection;
324+
325+
class PaymentMethods extends Enum
326+
{
327+
/**
328+
* @return static
329+
*/
330+
final public static function payPal(): self
331+
{
332+
return static::get('paypal', 'PayPal');
333+
}
334+
335+
/**
336+
* @return static
337+
*/
338+
final public static function stripe(): self
339+
{
340+
return static::get('stripe', 'Stripe');
341+
}
342+
343+
/**
344+
* @return static
345+
*/
346+
final public static function mollie(): self
347+
{
348+
return static::get('mollie', 'Mollie');
349+
}
350+
351+
/**
352+
* Returns only enabled payment methods. Useful for validation or rendering payments UI
353+
* @return Collection|static[]
354+
*/
355+
public static function enabled(): Collection
356+
{
357+
return static::enum()->only(config('payments.enabled'));
358+
}
359+
}
360+
```
361+
362+
### `from($id)` only allows valid IDs
363+
364+
Well, this is expected. Calling `PaymentMethod::from('ideal')` will throw `OutOfBoundsException`.
365+
366+
### No serialization
367+
368+
Enum object instances cannot be serialized. Deserialized objects would get a different address in memory therefore, `===` would no longer work.
369+
Calling `serialize(PaymentMethod::stripe())` will throw a `RuntimeException`.
370+
371+
As a workaround it is better to store the ID instead of object itself. You still get the bonus of setters only accepting valid values.
372+
373+
```php
374+
<?php
375+
376+
class Payment
377+
{
378+
/** @var string */
379+
private $method;
380+
381+
public function setMethod(PaymentMethod $method)
382+
{
383+
$this->method = $method->id();
384+
}
385+
386+
public function getMethod(): PaymentMethod
387+
{
388+
return PaymentMethod::from($this->method);
389+
}
390+
}
391+
```
392+
393+
## Coming soon
394+
395+
* Laravel package to integrate this with automated casting in model values
396+
* More implementations of collections in other frameworks

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"ext-json": "*"
2828
},
2929
"require-dev": {
30-
"illuminate/support": ">=6",
30+
"illuminate/support": "^6|^7",
3131
"phpunit/phpunit": "^8.5.8"
3232
},
3333
"suggest": {

0 commit comments

Comments
 (0)