-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: capabilities with builder pattern
- Loading branch information
1 parent
be2c758
commit ec824e7
Showing
38 changed files
with
1,615 additions
and
112 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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 was deleted.
Oops, something went wrong.
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,14 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders; | ||
|
||
use Illuminate\Database\Eloquent\Model; | ||
|
||
interface Builder | ||
{ | ||
public function assign(): static; | ||
|
||
public function create(): static; | ||
|
||
public function get(): ?Model; | ||
} |
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,122 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders; | ||
|
||
use Guava\Capabilities\Builders\Concerns\CanCreateIfNotExists; | ||
use Guava\Capabilities\Builders\Concerns\HasAssignee; | ||
use Guava\Capabilities\Builders\Concerns\HasTenant; | ||
use Guava\Capabilities\Contracts\Capability as CapabilityContract; | ||
use Guava\Capabilities\Facades\Capabilities; | ||
use Guava\Capabilities\Models\Capability; | ||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Support\Stringable; | ||
|
||
class CapabilityBuilder implements Builder | ||
{ | ||
use CanCreateIfNotExists; | ||
use HasAssignee; | ||
use HasTenant; | ||
|
||
protected CapabilityContract $configuration; | ||
|
||
protected ?Capability $model = null; | ||
|
||
public function __construct(string | CapabilityContract $capability, string|Model|null $model = null) | ||
{ | ||
$this->configuration = static::configuration($capability instanceof CapabilityContract | ||
? $capability->getName() | ||
: $capability, $model); | ||
// $this->configuration = $capability instanceof CapabilityContract | ||
// ? $capability | ||
// : static::configuration($capability, $model); | ||
} | ||
|
||
public function assign(?Model $assignee = null, ?Model $tenant = null): static | ||
{ | ||
$assignee ??= $this->getAssignee(); | ||
if (! $assignee) { | ||
return $this; | ||
} | ||
|
||
$tenant ??= $this->getTenant(); | ||
|
||
$model = $this->get(); | ||
|
||
if (! $model && $this->shouldCreateIfNotExists()) { | ||
$model = $this->create()->get(); | ||
} | ||
|
||
if ($model) { | ||
$assignee->assignCapability($model, $tenant); | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
public function create(): static | ||
{ | ||
$this->model = Capabilities::capability()->create([ | ||
'name' => $this->configuration->getName(), | ||
]); | ||
|
||
return $this; | ||
} | ||
|
||
public function get(): ?Model | ||
{ | ||
return $this->model ?? $this->find(); | ||
} | ||
|
||
private function find(): ?Capability | ||
{ | ||
return Capabilities::capability()->firstWhere([ | ||
'name' => $this->configuration->getName(), | ||
]); | ||
} | ||
|
||
public static function of(string | CapabilityContract $capability, string | Model | null $model = null) | ||
{ | ||
return app(static::class, ['capability' => $capability, 'model' => $model]); | ||
} | ||
|
||
private static function configuration(string $name, string | Model | null $model = null): CapabilityContract | ||
{ | ||
$record = null; | ||
if ($model instanceof Model) { | ||
$record = $model; | ||
$model = $record::class; | ||
} | ||
|
||
return new class($name, $model, $record) implements CapabilityContract | ||
{ | ||
public function __construct( | ||
private string $name, | ||
private ?string $model = null, | ||
private ?Model $record = null, | ||
) {} | ||
|
||
public function getName(): string | ||
{ | ||
return str($this->name) | ||
->when( | ||
$this->model, | ||
fn (Stringable $stringable) => $stringable | ||
->prepend('.') | ||
->prepend(str(class_basename($this->model))->kebab()) | ||
) | ||
->when( | ||
$this->record, | ||
fn (Stringable $stringable) => $stringable | ||
->append('.') | ||
->append($this->record->getKey()) | ||
) | ||
; | ||
} | ||
|
||
public function getModel(): ?string | ||
{ | ||
return null; | ||
} | ||
}; | ||
} | ||
} |
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,20 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders\Concerns; | ||
|
||
trait CanCreateIfNotExists | ||
{ | ||
private bool $createIfNotExists = false; | ||
|
||
public function createIfNotExists(bool $condition = true): static | ||
{ | ||
$this->createIfNotExists = $condition; | ||
|
||
return $this; | ||
} | ||
|
||
protected function shouldCreateIfNotExists(): bool | ||
{ | ||
return $this->createIfNotExists; | ||
} | ||
} |
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,22 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders\Concerns; | ||
|
||
use Illuminate\Database\Eloquent\Model; | ||
|
||
trait HasAssignee | ||
{ | ||
private ?Model $assignee = null; | ||
|
||
public function assignee(Model $assignee): static | ||
{ | ||
$this->assignee = $assignee; | ||
|
||
return $this; | ||
} | ||
|
||
protected function getAssignee(): ?Model | ||
{ | ||
return $this->assignee; | ||
} | ||
} |
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,22 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders\Concerns; | ||
|
||
use Illuminate\Support\Collection; | ||
|
||
trait HasCapabilities | ||
{ | ||
private ?Collection $capabilities = null; | ||
|
||
public function capabilities(array | Collection $capabilities): static | ||
{ | ||
$this->capabilities = collect($capabilities); | ||
|
||
return $this; | ||
} | ||
|
||
protected function getCapabilities(): Collection | ||
{ | ||
return $this->capabilities ?? collect(); | ||
} | ||
} |
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,28 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders\Concerns; | ||
|
||
use Guava\Capabilities\Exceptions\TenancyNotEnabledException; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
trait HasOwner | ||
{ | ||
private ?Model $owner = null; | ||
|
||
public function owner(Model $owner): static | ||
{ | ||
$this->owner = $owner; | ||
|
||
return $this; | ||
} | ||
|
||
protected function getOwner(): ?Model | ||
{ | ||
// TODO: Maybe refactor into 'capabilities.ownership' and differenciate between 'ownership' and 'tenancy' | ||
if (! config('capabilities.tenancy', false)) { | ||
throw TenancyNotEnabledException::make(); | ||
} | ||
|
||
return $this->owner; | ||
} | ||
} |
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,27 @@ | ||
<?php | ||
|
||
namespace Guava\Capabilities\Builders\Concerns; | ||
|
||
use Guava\Capabilities\Exceptions\TenancyNotEnabledException; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
trait HasTenant | ||
{ | ||
private ?Model $tenant = null; | ||
|
||
public function tenant(Model $tenant): static | ||
{ | ||
$this->tenant = $tenant; | ||
|
||
return $this; | ||
} | ||
|
||
protected function getTenant(): ?Model | ||
{ | ||
if (! config('capabilities.tenancy', false)) { | ||
throw TenancyNotEnabledException::make(); | ||
} | ||
|
||
return $this->tenant; | ||
} | ||
} |
Oops, something went wrong.