• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

conedevelopment / bazar / 20618174962

31 Dec 2025 11:34AM UTC coverage: 64.117% (+0.006%) from 64.111%
20618174962

push

github

iamgergo
wip

1115 of 1739 relevant lines covered (64.12%)

18.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.41
/src/Fields/Items.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Cone\Bazar\Fields;
6

7
use Closure;
8
use Cone\Bazar\Models\Product;
9
use Cone\Bazar\Models\Variant;
10
use Cone\Root\Fields\MorphMany;
11
use Cone\Root\Fields\MorphTo;
12
use Cone\Root\Fields\Number;
13
use Cone\Root\Fields\Text;
14
use Illuminate\Database\Eloquent\Model;
15
use Illuminate\Http\Request;
16

17
class Items extends MorphMany
18
{
19
    /**
20
     * The relations to eager load on every query.
21
     */
22
    protected array $with = [
23
        'buyable',
24
        'checkoutable',
25
        'taxes',
26
    ];
27

28
    /**
29
     * The buyable types.
30
     */
31
    protected array $buyableTypes = [];
32

33
    /**
34
     * The buyable searchable columns.
35
     */
36
    protected array $buyableSearchableColumns = [];
37

38
    /**
39
     * The buyable item display resolver.
40
     */
41
    protected ?Closure $buyableItemDisplayResolver = null;
42

43
    /**
44
     * Create a new relation field instance.
45
     */
46
    public function __construct(?string $label = null, Closure|string|null $modelAttribute = null, Closure|string|null $relation = null)
47
    {
48
        parent::__construct($label ?: __('Products'), $modelAttribute ?: 'items', $relation);
70✔
49

50
        $this->display('name');
70✔
51
        $this->asSubResource();
70✔
52

53
        $this->buyableTypes([
70✔
54
            Product::getProxiedClass(),
70✔
55
            Variant::getProxiedClass(),
70✔
56
        ]);
70✔
57

58
        $this->buyableSearchableColumns([
70✔
59
            Product::getProxiedClass() => ['id', 'name', 'slug', 'description'],
70✔
60
            Variant::getProxiedClass() => ['id', 'alias', 'description'],
70✔
61
        ]);
70✔
62
    }
63

64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function fields(Request $request): array
68
    {
69
        return [
70✔
70
            MorphTo::make(__('Buyable Item'), 'buyable')
70✔
71
                ->required()
70✔
72
                ->async()
70✔
73
                ->searchable(columns: $this->buyableSearchableColumns)
70✔
74
                ->types($this->buyableTypes)
70✔
75
                ->display(function (Model $buyable) use ($request): string {
70✔
76
                    return $this->resolveBuyableItemDisplay($request, $buyable);
×
77
                }),
70✔
78

79
            Text::make(__('Name'), 'name')
70✔
80
                ->required(),
70✔
81

82
            Number::make(__('Price'), 'price')
70✔
83
                ->min(0)
70✔
84
                ->required()
70✔
85
                ->format(static function (Request $request, Model $model, ?float $value): string {
70✔
86
                    return $model->checkoutable->getCurrency()->format($value ?? 0);
×
87
                }),
70✔
88

89
            Number::make(__('Tax'), function (Request $request, Model $model): float {
70✔
90
                return $model->getTax();
×
91
            })->format(static function (Request $request, Model $model, float $value): string {
70✔
92
                return $model->checkoutable->getCurrency()->format($value ?? 0);
×
93
            }),
70✔
94

95
            Number::make(__('Quantity'), 'quantity')
70✔
96
                ->required()
70✔
97
                ->default(1)
70✔
98
                ->rules(['required', 'numeric', 'gt:0'])
70✔
99
                ->min(0),
70✔
100

101
            Number::make(__('Total'), function (Request $request, Model $model): float {
70✔
102
                return $model->getTotal();
×
103
            })->format(static function (Request $request, Model $model, float $value): string {
70✔
104
                return $model->checkoutable->getCurrency()->format($value ?? 0);
×
105
            }),
70✔
106
        ];
70✔
107
    }
108

109
    /**
110
     * Set the buyable item display resolver.
111
     */
112
    public function displayBuyableItem(Closure $callback): static
113
    {
114
        $this->buyableItemDisplayResolver = $callback;
×
115

116
        return $this;
×
117
    }
118

119
    /**
120
     * Resolve the buyable item display.
121
     */
122
    public function resolveBuyableItemDisplay(Request $request, Model $buyable): string
123
    {
124
        $callback = $this->buyableItemDisplayResolver ?: static function (Request $request, Model $buyable): string {
×
125
            return (string) match ($buyable::class) {
×
126
                Product::getProxiedClass() => $buyable->name,
×
127
                Variant::getProxiedClass() => $buyable->alias,
×
128
                default => $buyable->getKey(),
×
129
            };
×
130
        };
×
131

132
        return call_user_func_array($callback, [$request, $buyable]);
×
133
    }
134

135
    /**
136
     * Set the buyable types.
137
     */
138
    public function buyableTypes(array $types): static
139
    {
140
        $this->buyableTypes = array_merge($this->buyableTypes, $types);
70✔
141

142
        return $this;
70✔
143
    }
144

145
    /**
146
     * Set the buyable searchable columns.
147
     */
148
    public function buyableSearchableColumns(array $columns): static
149
    {
150
        $this->buyableSearchableColumns = array_merge($this->buyableSearchableColumns, $columns);
70✔
151

152
        return $this;
70✔
153
    }
154
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc