Skip to content

Commit

Permalink
Implement encapsulation
Browse files Browse the repository at this point in the history
  • Loading branch information
cerbero90 committed Oct 27, 2024
1 parent 9858d34 commit 99d7e6f
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 0 deletions.
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ composer require cerbero/laravel-enum
* [🏷️ Meta](#%EF%B8%8F-meta)
* [🧺 Cases collection](#-cases-collection)
* [🪄 Magic](#-magic)
* [🪆 Encapsulation](#-encapsulation)

This package provides all the functionalities of [🎲 Enum](https://github.com/cerbero90/enum) plus Laravel specific features.

Expand Down Expand Up @@ -267,6 +268,55 @@ return [
Numbers::One->description(['value' => 1]);
```


### 🪆 Encapsulation

Laravel Enum offers some extra traits to encapsulate Laravel features that deal with keys. We can hold our keys in an enum (each case is a key) and use Laravel features without ever having to repeat such keys.

The benefits of this approach are many:
- no flaky strings around our codebase
- no keys misspelling
- IDE autocomplete
- reviewing/managing all our application keys in a central location
- updating one key in one file instead of all its occurrences

To encapsulate the Laravel session, we can create an enum holding all our session keys and let it use `EnumeratesSessionKeys`. Such enum can be either pure or backed:

```php
use Cerbero\LaravelEnum\Concerns\EnumeratesSessionKeys;

enum SessionKeys
{
use EnumeratesSessionKeys;

case CartItems;
case OnboardingStep;
case PageViews;
}
```

The `EnumeratesSessionKeys` trait also uses `Enumerates`, hence all the features of this package. We can now call all the Laravel session methods without having to worry about forgetting/misspelling keys:

```php
SessionKeys::CartItems->exists();
SessionKeys::CartItems->missing();
SessionKeys::CartItems->hasValue();
SessionKeys::CartItems->get($default);
SessionKeys::CartItems->pull($default);
SessionKeys::CartItems->hasOldInput();
SessionKeys::CartItems->getOldInput($default);
SessionKeys::CartItems->put($value);
SessionKeys::CartItems->remember($callback);
SessionKeys::CartItems->push($value);
SessionKeys::CartItems->increment($amount);
SessionKeys::CartItems->decrement($amount);
SessionKeys::CartItems->flash($value);
SessionKeys::CartItems->now($value);
SessionKeys::CartItems->remove();
SessionKeys::CartItems->forget();
```


## 📆 Change log

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
Expand Down
154 changes: 154 additions & 0 deletions src/Concerns/EnumeratesSessionKeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php

declare(strict_types=1);

namespace Cerbero\LaravelEnum\Concerns;

use Closure;
use Illuminate\Support\Facades\Session;

/**
* The trait to enumerate session keys.
*/
trait EnumeratesSessionKeys
{
use Enumerates;

/**
* Determine whether the key exists.
*/
public function exists(): bool
{
return Session::exists($this->value());
}

/**
* Determine whether the key is missing from the session.
*/
public function missing(): bool
{
return Session::missing($this->value());
}

/**
* Determine whether the key is present and not null.
*/
public function hasValue(): bool
{
return Session::has($this->value());
}

/**
* Retrieve the value of the key from the session.
*/
public function get(mixed $default = null): mixed
{
return Session::get($this->value(), $default);
}

/**
* Retrieve the value of the key and then forget it.
*/
public function pull(mixed $default = null): mixed
{
return Session::pull($this->value(), $default);
}

/**
* Determine whether the session contains old input for the key.
*/
public function hasOldInput(): bool
{
return Session::hasOldInput($this->value());
}

/**
* Retrieve the value from the flashed input.
*/
public function getOldInput(mixed $default = null): mixed
{
return Session::getOldInput($this->value(), $default);
}

/**
* Put the value of the key in the session.
*/
public function put(mixed $value = null): self
{
Session::put($this->value(), $value);

return $this;
}

/**
* Retrieve or store the value of the key.
*/
public function remember(Closure $callback): mixed
{
return Session::remember($this->value(), $callback);
}

/**
* Push a value onto the array of the key.
*/
public function push(mixed $value): self
{
Session::push($this->value(), $value);

return $this;
}

/**
* Increment the value of the key.
*/
public function increment(float|int $amount = 1): float|int
{
return Session::increment($this->value(), $amount);
}

/**
* Decrement the value of the key.
*/
public function decrement(float|int $amount = 1): float|int
{
return Session::decrement($this->value(), $amount);
}

/**
* Flash the value of the key to the session.
*/
public function flash(mixed $value = true): self
{
Session::flash($this->value(), $value);

return $this;
}

/**
* Flash the value of the key to the session for immediate use.
*/
public function now(mixed $value): self
{
Session::now($this->value(), $value);

return $this;
}

/**
* Remove the key from the session and retrieve its value.
*/
public function remove(): mixed
{
return Session::remove($this->value());
}

/**
* Remove the key from the session.
*/
public function forget(): self
{
Session::forget($this->value());

return $this;
}
}
102 changes: 102 additions & 0 deletions tests/Feature/SessionKeysTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

use Cerbero\LaravelEnum\SessionKeys;
use Illuminate\Support\Facades\Session;

it('supports the exists() method', function() {
Session::shouldReceive('exists')->with('PageViews')->andReturn(true);

expect(SessionKeys::PageViews->exists())->toBe(true);
});

it('supports the missing() method', function() {
Session::shouldReceive('missing')->with('PageViews')->andReturn(true);

expect(SessionKeys::PageViews->missing())->toBe(true);
});

it('supports the has() method', function() {
Session::shouldReceive('has')->with('PageViews')->andReturn(true);

expect(SessionKeys::PageViews->hasValue())->toBe(true);
});

it('supports the get() method', function() {
Session::shouldReceive('get')->with('PageViews', 123)->andReturn('foo');

expect(SessionKeys::PageViews->get(123))->toBe('foo');
});

it('supports the pull() method', function() {
Session::shouldReceive('pull')->with('PageViews', 123)->andReturn('foo');

expect(SessionKeys::PageViews->pull(123))->toBe('foo');
});

it('supports the hasOldInput() method', function() {
Session::shouldReceive('hasOldInput')->with('PageViews')->andReturn(true);

expect(SessionKeys::PageViews->hasOldInput())->toBe(true);
});

it('supports the getOldInput() method', function() {
Session::shouldReceive('getOldInput')->with('PageViews', 123)->andReturn('foo');

expect(SessionKeys::PageViews->getOldInput(123))->toBe('foo');
});

it('supports the put() method', function() {
Session::shouldReceive('put')->with('PageViews', 123);

expect(SessionKeys::PageViews->put(123))->toBe(SessionKeys::PageViews);
});

it('supports the remember() method', function() {
$expectedCallback = Mockery::on(fn(Closure $callback) => $callback() === 'foo');

Session::shouldReceive('remember')->with('PageViews', $expectedCallback)->andReturn('foo');

expect(SessionKeys::PageViews->remember(fn() => 'foo'))->toBe('foo');
});

it('supports the push() method', function() {
Session::shouldReceive('push')->with('PageViews', 123);

expect(SessionKeys::PageViews->push(123))->toBe(SessionKeys::PageViews);
});

it('supports the increment() method', function() {
Session::shouldReceive('increment')->with('PageViews', 2)->andReturn(10);

expect(SessionKeys::PageViews->increment(2))->toBe(10);
});

it('supports the decrement() method', function() {
Session::shouldReceive('decrement')->with('PageViews', 2)->andReturn(10);

expect(SessionKeys::PageViews->decrement(2))->toBe(10);
});

it('supports the flash() method', function() {
Session::shouldReceive('flash')->with('PageViews', 123);

expect(SessionKeys::PageViews->flash(123))->toBe(SessionKeys::PageViews);
});

it('supports the now() method', function() {
Session::shouldReceive('now')->with('PageViews', 123);

expect(SessionKeys::PageViews->now(123))->toBe(SessionKeys::PageViews);
});

it('supports the remove() method', function() {
Session::shouldReceive('remove')->with('PageViews')->andReturn('foo');

expect(SessionKeys::PageViews->remove())->toBe('foo');
});

it('supports the forget() method', function() {
Session::shouldReceive('forget')->with('PageViews');

expect(SessionKeys::PageViews->forget())->toBe(SessionKeys::PageViews);
});
17 changes: 17 additions & 0 deletions tests/SessionKeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Cerbero\LaravelEnum;

use Cerbero\LaravelEnum\Concerns\EnumeratesSessionKeys;

/**
* The enum of session keys.
*/
enum SessionKeys
{
use EnumeratesSessionKeys;

case PageViews;
}

0 comments on commit 99d7e6f

Please sign in to comment.