diff --git a/app/Http/Controllers/FoodController.php b/app/Http/Controllers/FoodController.php index fc9d4bb..5718274 100644 --- a/app/Http/Controllers/FoodController.php +++ b/app/Http/Controllers/FoodController.php @@ -83,6 +83,7 @@ class FoodController extends Controller 'notes' => 'nullable|string', 'serving_size' => ['required', new StringIsDecimalOrFraction], 'serving_unit' => 'nullable|string', + 'serving_unit_name' => 'nullable|string', 'serving_weight' => 'required|numeric', 'calories' => 'nullable|numeric', 'fat' => 'nullable|numeric', @@ -93,7 +94,7 @@ class FoodController extends Controller ]); $attributes['serving_size'] = Number::floatFromString($attributes['serving_size']); $attributes['name'] = Str::lower($attributes['name']); - $food->fill(array_filter($attributes))->save(); + $food->fill($attributes)->save(); // Sync tags. if ($tags = $request->get('tags')) { diff --git a/app/JsonApi/Schemas/FoodSchema.php b/app/JsonApi/Schemas/FoodSchema.php index 2fd35df..5225989 100644 --- a/app/JsonApi/Schemas/FoodSchema.php +++ b/app/JsonApi/Schemas/FoodSchema.php @@ -41,6 +41,7 @@ class FoodSchema extends SchemaProvider 'servingSize' => $resource->serving_size, 'servingSizeFormatted' => $resource->serving_size_formatted, 'servingUnit' => $resource->serving_unit, + 'servingUnitFormatted' => $resource->serving_unit_formatted, 'servingWeight' => $resource->serving_weight, 'createdAt' => $resource->created_at, 'updatedAt' => $resource->updated_at, diff --git a/app/Models/Food.php b/app/Models/Food.php index bfe7066..463b120 100644 --- a/app/Models/Food.php +++ b/app/Models/Food.php @@ -96,6 +96,7 @@ final class Food extends Model 'sodium', 'serving_size', 'serving_unit', + 'serving_unit_name', 'serving_weight', ]; @@ -116,7 +117,10 @@ final class Food extends Model /** * @inheritdoc */ - protected $appends = ['serving_size_formatted']; + protected $appends = [ + 'serving_size_formatted', + 'serving_unit_formatted' + ]; /** * Get the serving size as a formatted string (e.g. 0.5 = 1/2). @@ -125,4 +129,15 @@ final class Food extends Model return Number::fractionStringFromFloat($this->serving_size); } + /** + * Get the "formatted" serving unit (for custom unit support). + */ + public function getServingUnitFormattedAttribute(): ?string { + $unit = $this->serving_unit; + if (empty($unit)) { + $unit = $this->serving_unit_name ?? null; + } + return $unit; + } + } diff --git a/app/Models/IngredientAmount.php b/app/Models/IngredientAmount.php index 357132e..5f1c493 100644 --- a/app/Models/IngredientAmount.php +++ b/app/Models/IngredientAmount.php @@ -7,6 +7,7 @@ use App\Support\Nutrients; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Support\Pluralizer; /** * App\Models\IngredientAmount @@ -83,7 +84,7 @@ final class IngredientAmount extends Model /** * @inheritdoc */ - protected $appends = ['amount_formatted']; + protected $appends = ['amount_formatted', 'unit_formatted']; /** * Get the amount as a formatted string (e.g. 0.5 = 1/2). @@ -92,6 +93,26 @@ final class IngredientAmount extends Model return Number::fractionStringFromFloat($this->amount); } + /** + * Get a "formatted" unit. + * + * @see \App\Models\Food::getServingUnitFormattedAttribute() + */ + public function getUnitFormattedAttribute(): ?string { + $unit = $this->unit; + + // Inherit formatted unit from Food. + if ($unit === 'serving' && $this->ingredient->type === Food::class) { + $unit = $this->ingredient->serving_unit_formatted; + } + + if ($unit && $unit != 'tsp' && $unit != 'tbsp') { + $unit = Pluralizer::plural($unit, ceil($this->amount)); + } + + return $unit; + } + /** * Get the ingredient type (Food or Recipe). */ diff --git a/app/Models/Traits/Ingredient.php b/app/Models/Traits/Ingredient.php index eecfbcd..80c6dd3 100644 --- a/app/Models/Traits/Ingredient.php +++ b/app/Models/Traits/Ingredient.php @@ -16,7 +16,7 @@ trait Ingredient } /** - * Gets the class name. + * Get the class name. * * This is necessary e.g. to provide data in ingredient picker responses. */ @@ -32,7 +32,7 @@ trait Ingredient } /** - * Gets search results for a term. + * Get search results for a term. */ public static function search(string $term, int $limit = 10): Collection { return (new static)::where('name', 'like', "%{$term}%")->limit($limit)->get(); diff --git a/database/migrations/2021_02_03_205453_add_serving_unit_name_field_to_foods.php b/database/migrations/2021_02_03_205453_add_serving_unit_name_field_to_foods.php new file mode 100644 index 0000000..dfe2f80 --- /dev/null +++ b/database/migrations/2021_02_03_205453_add_serving_unit_name_field_to_foods.php @@ -0,0 +1,32 @@ +string('serving_unit_name')->nullable()->after('serving_unit'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('foods', function (Blueprint $table) { + $table->dropColumn(['serving_unit_name']); + }); + } +} diff --git a/resources/views/foods/edit.blade.php b/resources/views/foods/edit.blade.php index 61ea2ec..bd8880d 100644 --- a/resources/views/foods/edit.blade.php +++ b/resources/views/foods/edit.blade.php @@ -82,6 +82,18 @@ + +