Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
95.83% |
23 / 24 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
| ProductCarousel | |
95.83% |
23 / 24 |
|
83.33% |
5 / 6 |
9 | |
0.00% |
0 / 1 |
| key | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| label | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| icon | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| description | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| fields | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
1 | |||
| products | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
4.02 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Widgets\Types; |
| 4 | |
| 5 | use App\Models\admin\Product; |
| 6 | use App\Models\Category; |
| 7 | use App\Models\ProductCollection; |
| 8 | use App\Widgets\AbstractWidget; |
| 9 | use Illuminate\Support\Collection; |
| 10 | |
| 11 | class ProductCarousel extends AbstractWidget |
| 12 | { |
| 13 | protected string $view = 'widgets.product-carousel'; |
| 14 | |
| 15 | public function key(): string |
| 16 | { |
| 17 | return 'product_carousel'; |
| 18 | } |
| 19 | |
| 20 | public function label(): string |
| 21 | { |
| 22 | return 'Product row'; |
| 23 | } |
| 24 | |
| 25 | public function icon(): string |
| 26 | { |
| 27 | return 'fas fa-boxes-stacked'; |
| 28 | } |
| 29 | |
| 30 | public function description(): string |
| 31 | { |
| 32 | return 'A row of products — newest, featured, or from a category.'; |
| 33 | } |
| 34 | |
| 35 | public function fields(): array |
| 36 | { |
| 37 | return [ |
| 38 | 'title' => ['type' => 'text', 'label' => 'Heading', 'default' => "What's new"], |
| 39 | 'layout' => ['type' => 'select', 'label' => 'Layout', 'default' => 'carousel', |
| 40 | 'options' => ['carousel' => 'Sliding carousel', 'grid' => 'Static grid']], |
| 41 | 'source' => ['type' => 'select', 'label' => 'Show', 'default' => 'newest', |
| 42 | 'options' => ['newest' => 'Newest products', 'featured' => 'Featured products', 'category' => 'From a category', 'collection'=>'From a collection']], |
| 43 | 'category_id' => ['type' => 'select', 'label' => 'Category', 'default' => '', 'options' => [''=>'Choose category'] + Category::orderBy('name')->pluck('name','id')->all()], |
| 44 | 'collection_id' => ['type' => 'select', 'label' => 'Collection', 'default' => '', 'options' => [''=>'Choose collection'] + ProductCollection::where('is_active',true)->orderBy('name')->pluck('name','id')->all()], |
| 45 | 'limit' => ['type' => 'number', 'label' => 'How many', 'default' => 8], |
| 46 | ]; |
| 47 | } |
| 48 | |
| 49 | /** @return Collection<int,Product> */ |
| 50 | public function products(array $s) |
| 51 | { |
| 52 | $limit = max(1, min(48, (int) ($s['limit'] ?? 8))); |
| 53 | |
| 54 | if (($s['source'] ?? '') === 'collection' && ! empty($s['collection_id'])) { |
| 55 | return ProductCollection::find($s['collection_id'])?->products()->limit($limit)->get() ?? collect(); |
| 56 | } |
| 57 | |
| 58 | return Product::query() |
| 59 | ->when(($s['source'] ?? '') === 'featured', fn ($q) => $q->where('is_featured', true)) |
| 60 | ->when(($s['source'] ?? '') === 'category' && ! empty($s['category_id']), |
| 61 | fn ($q) => $q->where('category_id', $s['category_id'])) |
| 62 | ->latest() |
| 63 | ->limit($limit) |
| 64 | ->get(); |
| 65 | } |
| 66 | } |