Skip to content

Instantly share code, notes, and snippets.

@jalallinux
Last active January 14, 2024 09:03
Show Gist options
  • Save jalallinux/971cab44ef3646cb871ade5dd9a2286d to your computer and use it in GitHub Desktop.
Save jalallinux/971cab44ef3646cb871ade5dd9a2286d to your computer and use it in GitHub Desktop.
OTP class
<?php
namespace App\Contracts;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
class Otp implements Arrayable, Jsonable
{
/**
* Generate a string where ? characters are replaced with a random letter,
* and # characters are replaces with a random digit between 0 and 10.
*
* @source https://fakerphp.github.io/formatters/numbers-and-strings/#bothify
*/
const FORMAT = '######';
private string $id;
private string $tag;
private string $code;
private string $ttl;
public static function make(string $id = null, string $code = null, string $tag = null, string $format = null, string $ttl = null): static
{
$codeMethod = is_null($code) ? 'withRandomCode' : 'withCode';
return (new self)
->withId($id)
->{$codeMethod}(is_null($code) ? self::FORMAT : $code)
->withTag($tag ?? 'default')
->withTtl($ttl ?? '+20 minutes');
}
public static function fromArray(array $arr)
{
return self::make(
id: @$arr['id'],
code: @$arr['code'],
tag: @$arr['tag'],
format: @$arr['format'],
ttl: @$arr['ttl']
);
}
public function id(): string
{
return $this->id;
}
public function tag(): string
{
return $this->tag;
}
public function code(): string
{
return $this->code;
}
public function ttl(): Carbon
{
return Carbon::parse($this->ttl);
}
private function withId(string $id = null): static
{
return tap($this, fn () => $this->id = $id ?? Str::uuid()->toString());
}
public function withTag(string $tag): static
{
return tap($this, fn () => $this->tag = $tag);
}
public function withRandomCode(string $format = self::FORMAT): static
{
return tap($this, fn () => $this->code = fake()->bothify($format));
}
public function withCode(string $code): static
{
return tap($this, fn () => $this->code = $code);
}
public function withTtl(string $ttl): static
{
return tap($this, fn () => $this->ttl = $ttl);
}
public function toArray(): array
{
return [
'id' => $this->id,
'tag' => $this->tag,
'code' => $this->code,
'ttl' => $this->ttl,
];
}
public function toJson($options = 0): string
{
return json_encode($this->toArray());
}
}
<?php
namespace App\Contracts\Trait;
use App\Contracts\Otp;
use Illuminate\Support\Facades\Cache;
trait WithOtp
{
public function otp(string $id = null, string $tag = 'default'): ?Otp
{
if (!is_null($id)) {
$otp = Cache::tags($tag)->get($id);
return is_null($otp) ? Otp::make(id: $id, tag: $tag) : Otp::fromArray($otp);
}
$otp = Otp::make(tag: $tag);
Cache::tags($tag)->put($otp->id(), $otp->toArray(), $otp->ttl()->toDateTime());
return $otp;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment