Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ThemeController
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
3 / 3
7
100.00% covered (success)
100.00%
1 / 1
 __invoke
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 menus
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 widgets
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Api\ApiController;
6use App\Models\Widget;
7use App\Services\Builder\MenuService;
8use App\Services\Builder\WidgetService;
9use App\Services\Theme\ThemeService;
10use Illuminate\Http\JsonResponse;
11
12/**
13 * GET /api/v1/theme
14 *
15 * Everything a JS frontend needs to render the same storefront structure the
16 * Blade themes render: the active theme, its customiser values, the menu
17 * trees per location, and the widget stack per area.
18 */
19class ThemeController extends ApiController
20{
21    public function __invoke(ThemeService $themes, MenuService $menus, WidgetService $widgets): JsonResponse
22    {
23        $active = $themes->active();
24
25        return $this->respond([
26            'theme' => [
27                'handle' => $active['handle'],
28                'name' => $active['name'],
29                'version' => $active['version'],
30            ],
31            'customizer' => $themes->activeCustomizer(),
32            'menus' => $this->menus($menus),
33            'widgets' => $this->widgets($widgets),
34        ]);
35    }
36
37    /** @return array<string, array> location => tree */
38    private function menus(MenuService $menus): array
39    {
40        $out = [];
41        foreach (array_keys(config('builder.menu_locations', [])) as $location) {
42            $tree = $menus->forLocation($location);
43            if ($tree !== []) {
44                $out[$location] = $tree;
45            }
46        }
47
48        return $out;
49    }
50
51    /** @return array<string, array> area => [ {type, settings}, ... ] */
52    private function widgets(WidgetService $widgets): array
53    {
54        $out = [];
55        foreach (array_keys(config('builder.widget_areas', [])) as $area) {
56            $blocks = $widgets->area($area)
57                ->map(fn (Widget $w) => [
58                    'type' => $w->type,
59                    'settings' => $w->settings ?? [],
60                ])
61                ->all();
62
63            if ($blocks !== []) {
64                $out[$area] = $blocks;
65            }
66        }
67
68        return $out;
69    }
70}