mirror of https://github.com/kcal-app/kcal.git
Add API endpoint and relationships for recipe separators
This commit is contained in:
parent
91af802c2f
commit
e97056553a
|
@ -70,6 +70,14 @@ class RecipeAdapter extends AbstractAdapter
|
|||
return $this->morphMany($this->hasMany('media'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ingredient amount relationships.
|
||||
*/
|
||||
protected function separators(): HasMany
|
||||
{
|
||||
return $this->hasMany();
|
||||
}
|
||||
|
||||
/**
|
||||
* Step relationships.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\JsonApi\Adapters;
|
||||
|
||||
use App\Models\RecipeSeparator;
|
||||
use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter;
|
||||
use CloudCreativity\LaravelJsonApi\Eloquent\BelongsTo;
|
||||
use CloudCreativity\LaravelJsonApi\Pagination\StandardStrategy;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class RecipeSeparatorAdapter extends AbstractAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $filterScopes = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultSort = ['weight'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(StandardStrategy $paging)
|
||||
{
|
||||
parent::__construct(new RecipeSeparator(), $paging);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function filter($query, Collection $filters)
|
||||
{
|
||||
$this->filterWithScopes($query, $filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recipe relationship.
|
||||
*/
|
||||
protected function recipe(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo();
|
||||
}
|
||||
|
||||
}
|
|
@ -62,7 +62,6 @@ class RecipeSchema extends SchemaProvider
|
|||
{
|
||||
return [
|
||||
'ingredient-amounts' => [
|
||||
self::SHOW_SELF => true,
|
||||
self::SHOW_RELATED => true,
|
||||
self::SHOW_DATA => isset($includeRelationships['ingredient-amounts']),
|
||||
self::DATA => function () use ($resource) {
|
||||
|
@ -70,15 +69,20 @@ class RecipeSchema extends SchemaProvider
|
|||
},
|
||||
],
|
||||
'media' => [
|
||||
self::SHOW_SELF => true,
|
||||
self::SHOW_RELATED => true,
|
||||
self::SHOW_DATA => isset($includeRelationships['media']),
|
||||
self::DATA => function () use ($resource) {
|
||||
return $resource->media;
|
||||
},
|
||||
],
|
||||
'separators' => [
|
||||
self::SHOW_RELATED => true,
|
||||
self::SHOW_DATA => isset($includeRelationships['separators']),
|
||||
self::DATA => function () use ($resource) {
|
||||
return $resource->separators;
|
||||
},
|
||||
],
|
||||
'steps' => [
|
||||
self::SHOW_SELF => true,
|
||||
self::SHOW_RELATED => true,
|
||||
self::SHOW_DATA => isset($includeRelationships['steps']),
|
||||
self::DATA => function () use ($resource) {
|
||||
|
@ -86,7 +90,6 @@ class RecipeSchema extends SchemaProvider
|
|||
},
|
||||
],
|
||||
'tags' => [
|
||||
self::SHOW_SELF => true,
|
||||
self::SHOW_RELATED => true,
|
||||
self::SHOW_DATA => isset($includeRelationships['tags']),
|
||||
self::DATA => function () use ($resource) {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\JsonApi\Schemas;
|
||||
|
||||
use Neomerx\JsonApi\Schema\SchemaProvider;
|
||||
|
||||
class RecipeSeparatorSchema extends SchemaProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $resourceType = 'recipe-separators';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getId($resource): string
|
||||
{
|
||||
return (string) $resource->getRouteKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
return [
|
||||
'container' => $resource->container,
|
||||
'weight' => $resource->weight,
|
||||
'text' => $resource->text,
|
||||
'createdAt' => $resource->created_at,
|
||||
'updatedAt' => $resource->updated_at,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getRelationships($resource, $isPrimary, array $includeRelationships): array
|
||||
{
|
||||
return [
|
||||
'recipe' => [
|
||||
self::SHOW_SELF => true,
|
||||
self::SHOW_RELATED => true,
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
|
@ -75,6 +75,8 @@ use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
|||
* @method static \Database\Factories\RecipeFactory factory(...$parameters)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereTimeCook($value)
|
||||
* @property-read Collection $ingredients_list
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\RecipeSeparator[] $separators
|
||||
* @property-read int|null $separators_count
|
||||
*/
|
||||
final class Recipe extends Model implements HasMedia
|
||||
{
|
||||
|
@ -182,14 +184,23 @@ final class Recipe extends Model implements HasMedia
|
|||
}
|
||||
|
||||
/**
|
||||
* Get "separators" for the ingredients.
|
||||
* Get "separators" for the recipe.
|
||||
*
|
||||
* Separators are used to adding headings or simple separations to the
|
||||
* Separators are used to add headings or simple separations to the
|
||||
* ingredients _list_ for a recipe. Their position is defined by weights
|
||||
* compatible with ingredient weights.
|
||||
*
|
||||
* @todo Add support for step separators
|
||||
*/
|
||||
public function separators(): HasMany {
|
||||
return $this->hasMany(RecipeSeparator::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ingredient separators.
|
||||
*/
|
||||
public function ingredientSeparators(): HasMany {
|
||||
return $this->hasMany(RecipeSeparator::class)
|
||||
return $this->separators()
|
||||
->where('container', 'ingredients')
|
||||
->orderBy('weight');
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ return [
|
|||
'media' => \Spatie\MediaLibrary\MediaCollections\Models\Media::class,
|
||||
'journal-entries' => \App\Models\JournalEntry::class,
|
||||
'recipes' => \App\Models\Recipe::class,
|
||||
'recipe-separators' => \App\Models\RecipeSeparator::class,
|
||||
'recipe-steps' => \App\Models\RecipeStep::class,
|
||||
'tags' => \App\Models\Tag::class,
|
||||
'users' => \App\Models\User::class,
|
||||
|
|
|
@ -30,9 +30,13 @@ JsonApi::register('v1')->routes(function ($api) {
|
|||
$api->resource('recipes')->relationships(function ($relations) {
|
||||
$relations->hasMany('ingredient-amounts')->readOnly();
|
||||
$relations->hasMany('media')->readOnly();
|
||||
$relations->hasMany('separators')->readOnly();
|
||||
$relations->hasMany('steps')->readOnly();
|
||||
$relations->hasMany('tags')->readOnly();
|
||||
})->readOnly();
|
||||
$api->resource('recipe-separators')->relationships(function ($relations) {
|
||||
$relations->hasOne('recipe')->readOnly();
|
||||
})->readOnly();
|
||||
$api->resource('recipe-steps')->relationships(function ($relations) {
|
||||
$relations->hasOne('recipe')->readOnly();
|
||||
})->readOnly();
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\JsonApi;
|
||||
|
||||
use App\Models\Recipe;
|
||||
use App\Models\RecipeSeparator;
|
||||
use Database\Factories\RecipeSeparatorFactory;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class RecipeSeparatorApiTest extends JsonApiTestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function factory(): RecipeSeparatorFactory
|
||||
{
|
||||
return RecipeSeparator::factory();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function resourceName(): string
|
||||
{
|
||||
return 'recipe-separators';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function createInstances(int $count = 1): Collection {
|
||||
return Recipe::factory()->count(1)->hasSeparators($count)->create();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue