Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,45 @@ $postData->locations->firstWhere('slug', 'utrecht')->name; // Utrecht
$vacancyData->locations->implode('name', ', '), // Almere, Amsterdam, Utrecht
```

#### Extending TermData

You can add extra meta fields to taxonomies by extending the default TermData object

```php
namespace App\Data;

use Yard\Data\TermData;

class TypeTermData extends TermData {

#[Meta()]
public string $icon;
}

```

In your PostData object you have to specify the data class used for a specific taxonomy:

```php
namespace App\Data;

use Illuminate\Support\Collection;
use Yard\Data\Attributes\TaxonomyPrefix;
use Yard\Data\Attributes\Terms;
use Yard\Data\PostData;

class VacancyData extends PostData
{
#[Terms(dataClass: TypeTermData::class)]
/** @var Collection<int, TypeTermData> */
public Collection $type;
}
```

```php
$vacancyTypeIcon = $vacancyData->type->first()?->icon;
```

### UserData

Create UserData from current user:
Expand Down
6 changes: 3 additions & 3 deletions src/Attributes/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public function __construct(private ?string $metaKey = null)
{
}

public function getValue(int $postID, string $metaKey, string $prefix): mixed
public function getValue(string|int $objectID, string $metaKey, string $prefix): mixed
{
if (isset($this->metaKey)) {
if ($value = \get_field($this->metaKey, $postID)) {
if ($value = \get_field($this->metaKey, $objectID)) {
return $value;
} else {
return null;
Expand All @@ -31,7 +31,7 @@ public function getValue(int $postID, string $metaKey, string $prefix): mixed
];

foreach ($possibleKeys as $key) {
if ($value = \get_field($key, $postID)) {
if ($value = \get_field($key, $objectID)) {
return $value;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Attributes/Terms.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#[\Attribute(\Attribute::TARGET_PROPERTY)]
class Terms
{
public function __construct(private ?string $taxonomy = null)
public function __construct(private ?string $taxonomy = null, private string $dataClass = TermData::class)
{
}

Expand Down Expand Up @@ -41,7 +41,7 @@ public function getValue(int $postID, string $taxonomy, string $prefix): mixed
return null;
}

return TermData::collect($terms, Collection::class);
return $this->dataClass::collect($terms, Collection::class);
}
}

Expand Down
43 changes: 4 additions & 39 deletions src/PostData.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@

namespace Yard\Data;

use BackedEnum;
use Carbon\CarbonImmutable;
use Corcel\Model\Post;
use Illuminate\Support\Collection;
use ReflectionClass;
use ReflectionNamedType;
use RuntimeException;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\WithCastable;
Expand All @@ -20,18 +18,19 @@
use Spatie\LaravelData\Normalizers\ModelNormalizer;
use Spatie\LaravelData\Normalizers\Normalizer;
use Spatie\LaravelData\Normalizers\ObjectNormalizer;
use Yard\Data\Attributes\Meta;
use Yard\Data\Attributes\MetaPrefix;
use Yard\Data\Attributes\TaxonomyPrefix;
use Yard\Data\Attributes\Terms;
use Yard\Data\Contracts\PostDataInterface;
use Yard\Data\Enums\PostStatus;
use Yard\Data\Mappers\PostPrefixMapper;
use Yard\Data\Normalizers\WPPostNormalizer;
use Yard\Data\Traits\HasMeta;

#[MapInputName(PostPrefixMapper::class)]
class PostData extends Data implements PostDataInterface
{
use HasMeta;

public function __construct(
#[MapInputName('ID')]
public ?int $id,
Expand All @@ -49,7 +48,7 @@ public function __construct(
public ?ImageData $thumbnail,
) {
if (null !== $id) {
$this->loadMeta($id);
$this->loadMeta();
$this->loadTerms($id);
}
}
Expand Down Expand Up @@ -116,40 +115,6 @@ private static function dataClass(string $postType): string
return $classFQN;
}

private function metaPrefix(): string
{
$reflectionClass = new ReflectionClass($this);
$metaPrefixAttribute = $reflectionClass->getAttributes(MetaPrefix::class)[0] ?? null;

return $metaPrefixAttribute?->newInstance()->prefix ?? '';
}

private function loadMeta(int $id): void
{
$reflectionClass = new ReflectionClass($this);
$properties = $reflectionClass->getProperties();
foreach ($properties as $property) {
$propertyType = $property->getType();
$propertyTypeName = null;
if ($propertyType instanceof ReflectionNamedType) {
$propertyTypeName = $propertyType->getName();
}
$metaAttributes = $property->getAttributes(Meta::class);
foreach ($metaAttributes as $metaAttribute) {
$meta = $metaAttribute->newInstance();
$metaValue = $meta->getValue($id, $property->name, $this->metaPrefix());
if (null !== $metaValue && null !== $propertyTypeName) {
if (is_a($propertyTypeName, Data::class, true)) {
$metaValue = $propertyTypeName::from($metaValue);
} elseif (is_a($propertyTypeName, BackedEnum::class, true) && (is_int($metaValue) || is_string($metaValue))) {
$metaValue = $propertyTypeName::from($metaValue);
}
$property->setValue($this, $metaValue);
}
}
}
}

private function taxonomyPrefix(): string
{
$reflectionClass = new ReflectionClass($this);
Expand Down
19 changes: 14 additions & 5 deletions src/TermData.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,26 @@

use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Data;
use Yard\Data\Traits\HasMeta;

class TermData extends Data
{
#[MapInputName('term_id')]
public int $id;
public string $name;
public string $slug;
use HasMeta;

public function __construct(
#[MapInputName('term_id')]
public int $id,
public string $name,
public string $slug,
public string $taxonomy,
public ?string $description = null,
) {
$this->loadMeta();
}

public static function fromTerm(\WP_Term $term): TermData
{
return self::from(
return static::from(
$term->to_array()
);
}
Expand Down
60 changes: 60 additions & 0 deletions src/Traits/HasMeta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Yard\Data\Traits;

use Spatie\LaravelData\Data;
use Yard\Data\Attributes\Meta;
use Yard\Data\Attributes\MetaPrefix;
use Yard\Data\PostData;
use Yard\Data\TermData;

trait HasMeta
{
private function loadMeta(): void
{
$reflectionClass = new \ReflectionClass($this);
$properties = $reflectionClass->getProperties();
foreach ($properties as $property) {
$propertyType = $property->getType();
$propertyTypeName = null;
if ($propertyType instanceof \ReflectionNamedType) {
$propertyTypeName = $propertyType->getName();
}
$metaAttributes = $property->getAttributes(Meta::class);
foreach ($metaAttributes as $metaAttribute) {
$meta = $metaAttribute->newInstance();
$metaValue = $meta->getValue($this->objectID(), $property->name, $this->metaPrefix());
if (null !== $metaValue && null !== $propertyTypeName) {
if (is_a($propertyTypeName, Data::class, true)) {
$metaValue = $propertyTypeName::from($metaValue);
} elseif (is_a($propertyTypeName, \BackedEnum::class, true) && (is_int($metaValue) || is_string($metaValue))) {
$metaValue = $propertyTypeName::from($metaValue);
}
$property->setValue($this, $metaValue);
}
}
}
}

private function metaPrefix(): string
{
$reflectionClass = new \ReflectionClass($this);
$metaPrefixAttribute = $reflectionClass->getAttributes(MetaPrefix::class)[0] ?? null;

return $metaPrefixAttribute?->newInstance()->prefix ?? '';
}

private function objectID(): string|int
{
if (is_a($this, PostData::class)) {
return $this->id ?? 0;
}
if (is_a($this, TermData::class)) {
return $this->taxonomy . '_' . $this->id;
}

return 0;
}
}