Skip to content

Commit

Permalink
Added PrimaryKey attribute and refactored how to get attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
WendellAdriel committed May 6, 2024
1 parent 86aba7e commit b4abd37
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
18 changes: 18 additions & 0 deletions src/Models/Attributes/PrimaryKey.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace WendellAdriel\Virtue\Models\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
final class PrimaryKey
{
public function __construct(
public ?string $name = null,
public ?string $type = null,
public ?bool $incrementing = null,
) {
}
}
52 changes: 38 additions & 14 deletions src/Models/Concerns/Virtue.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@

namespace WendellAdriel\Virtue\Models\Concerns;

use Illuminate\Support\Collection;
use ReflectionAttribute;
use ReflectionClass;
use WendellAdriel\Virtue\Models\Attributes\Cast;
use WendellAdriel\Virtue\Models\Attributes\Database;
use WendellAdriel\Virtue\Models\Attributes\Fillable;
use WendellAdriel\Virtue\Models\Attributes\Hidden;
use WendellAdriel\Virtue\Models\Attributes\PrimaryKey;

trait Virtue
{
use HasRelations;

private ?ReflectionClass $reflectionClass = null;
private ?Collection $classAttributes = null;

public function initializeVirtue(): void
{
$this->applyDatabaseCustomizations();
$this->applyPrimaryKeyCustomization();
$this->applyFillable();
$this->applyHidden();
$this->applyCasts();
Expand All @@ -46,6 +49,27 @@ private function applyDatabaseCustomizations(): void
$this->timestamps = $databaseAttribute->timestamps;
}

private function applyPrimaryKeyCustomization(): void
{
/** @var ReflectionAttribute|null $attribute */
$attribute = $this->resolveSingleAttribute(PrimaryKey::class);
if (is_null($attribute)) {
return;
}

/** @var PrimaryKey $primaryKeyAttribute */
$primaryKeyAttribute = $attribute->newInstance();
if (! is_null($primaryKeyAttribute->name)) {
$this->setKeyName($primaryKeyAttribute->name);
}
if (! is_null($primaryKeyAttribute->type)) {
$this->setKeyType($primaryKeyAttribute->type);
}
if (! is_null($primaryKeyAttribute->incrementing)) {
$this->setIncrementing($primaryKeyAttribute->incrementing);
}
}

private function applyFillable(): void
{
/** @var ReflectionAttribute|null $attribute */
Expand All @@ -63,6 +87,7 @@ private function applyFillable(): void

private function applyHidden(): void
{
/** @var ReflectionAttribute|null $attribute */
$attribute = $this->resolveSingleAttribute(Hidden::class);
if (is_null($attribute)) {
return;
Expand All @@ -77,9 +102,8 @@ private function applyHidden(): void

private function applyCasts(): void
{
/** @var array<ReflectionAttribute>|null $castAttributes */
$castAttributes = $this->resolveMultipleAttributes(Cast::class);
if (is_null($castAttributes)) {
if ($castAttributes->isEmpty()) {
return;
}

Expand All @@ -100,26 +124,26 @@ private function applyCasts(): void
*/
private function resolveSingleAttribute(string $attributeClass): ?ReflectionAttribute
{
$reflectionClass = $this->reflectionClass();
$attributes = $reflectionClass->getAttributes($attributeClass);
$classAttributes = $this->classAttributes();

return $attributes === [] ? null : $attributes[0];
return $classAttributes->filter(fn (ReflectionAttribute $attribute) => $attribute->getName() === $attributeClass)
->first();
}

private function resolveMultipleAttributes(string $attributeClass): ?array
private function resolveMultipleAttributes(string $attributeClass): Collection
{
$reflectionClass = $this->reflectionClass();
$attributes = $reflectionClass->getAttributes($attributeClass);
$classAttributes = $this->classAttributes();

return $attributes === [] ? null : $attributes;
return $classAttributes->filter(fn (ReflectionAttribute $attribute) => $attribute->getName() === $attributeClass);
}

private function reflectionClass(): ReflectionClass
private function classAttributes(): Collection
{
if (is_null($this->reflectionClass)) {
$this->reflectionClass = new ReflectionClass(static::class);
if (is_null($this->classAttributes)) {
$reflectionClass = new ReflectionClass(static::class);
$this->classAttributes = Collection::make($reflectionClass->getAttributes());
}

return $this->reflectionClass;
return $this->classAttributes;
}
}

0 comments on commit b4abd37

Please sign in to comment.