Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ViteService
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 8
110
0.00% covered (danger)
0.00%
0 / 1
 createManifest
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 createTwigExtension
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 isDevServerEnabled
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getDevServerUrl
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getManifestPath
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getProjectRoot
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 setProjectRoot
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isBuildAvailable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace BuyerKiosk\Vite;
6
7/**
8 * Vite Service Factory
9 *
10 * Creates and configures Vite components with sensible defaults.
11 * Use this to get pre-configured instances for use in the application.
12 *
13 * Configuration via environment variables:
14 * - VITE_DEV_SERVER_ENABLED: Enable dev server mode (default: false)
15 * - VITE_DEV_SERVER_URL: Dev server URL (default: http://localhost:5173)
16 *
17 * @example
18 * // In config-userfrosting.php or initialize.php:
19 * $viteExtension = \BuyerKiosk\Vite\ViteService::createTwigExtension();
20 * $app->view()->parserExtensions[] = $viteExtension;
21 */
22class ViteService
23{
24    /**
25     * Default paths relative to project root
26     */
27    private const DEFAULT_MANIFEST_PATH = 'public_html/js/dist/.vite/manifest.json';
28    private const DEFAULT_BASE_URL = '/js/dist/';
29    private const DEFAULT_DEV_SERVER_URL = 'http://localhost:5173';
30
31    /**
32     * Project root path (auto-detected)
33     */
34    private static ?string $projectRoot = null;
35
36    /**
37     * Create a configured ViteManifest instance
38     *
39     * @param string|null $manifestPath Override manifest path
40     * @param string|null $baseUrl Override base URL
41     * @return ViteManifest
42     */
43    public static function createManifest(
44        ?string $manifestPath = null,
45        ?string $baseUrl = null
46    ): ViteManifest {
47        $manifestPath = $manifestPath ?? self::getManifestPath();
48        $baseUrl = $baseUrl ?? self::DEFAULT_BASE_URL;
49
50        return new ViteManifest($manifestPath, $baseUrl);
51    }
52
53    /**
54     * Create a configured ViteTwigExtension instance
55     *
56     * Reads configuration from environment variables:
57     * - VITE_DEV_SERVER_ENABLED: Enable dev server mode
58     * - VITE_DEV_SERVER_URL: Dev server URL
59     *
60     * @param ViteManifest|null $manifest Override manifest instance
61     * @param bool|null $devServerEnabled Override dev server enabled
62     * @param string|null $devServerUrl Override dev server URL
63     * @return ViteTwigExtension
64     */
65    public static function createTwigExtension(
66        ?ViteManifest $manifest = null,
67        ?bool $devServerEnabled = null,
68        ?string $devServerUrl = null
69    ): ViteTwigExtension {
70        $manifest = $manifest ?? self::createManifest();
71
72        // Read from environment if not explicitly provided
73        $devServerEnabled = $devServerEnabled ?? self::isDevServerEnabled();
74        $devServerUrl = $devServerUrl ?? self::getDevServerUrl();
75
76        return new ViteTwigExtension(
77            $manifest,
78            $devServerEnabled,
79            $devServerUrl,
80            true // renderErrors = true (show as HTML comments)
81        );
82    }
83
84    /**
85     * Check if dev server mode is enabled via environment
86     *
87     * @return bool
88     */
89    public static function isDevServerEnabled(): bool
90    {
91        $value = $_ENV['VITE_DEV_SERVER_ENABLED']
92            ?? getenv('VITE_DEV_SERVER_ENABLED')
93            ?? 'false';
94
95        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
96    }
97
98    /**
99     * Get dev server URL from environment
100     *
101     * @return string
102     */
103    public static function getDevServerUrl(): string
104    {
105        return $_ENV['VITE_DEV_SERVER_URL']
106            ?? getenv('VITE_DEV_SERVER_URL')
107            ?: self::DEFAULT_DEV_SERVER_URL;
108    }
109
110    /**
111     * Get the absolute path to the manifest file
112     *
113     * @return string
114     */
115    public static function getManifestPath(): string
116    {
117        return self::getProjectRoot() . '/' . self::DEFAULT_MANIFEST_PATH;
118    }
119
120    /**
121     * Get the project root directory
122     *
123     * @return string
124     */
125    public static function getProjectRoot(): string
126    {
127        if (self::$projectRoot !== null) {
128            return self::$projectRoot;
129        }
130
131        // Navigate up from userfrosting/src/BuyerKiosk/Vite/ to project root
132        self::$projectRoot = dirname(__DIR__, 4);
133
134        return self::$projectRoot;
135    }
136
137    /**
138     * Set the project root (useful for testing)
139     *
140     * @param string|null $path Project root path, or null to auto-detect
141     */
142    public static function setProjectRoot(?string $path): void
143    {
144        self::$projectRoot = $path;
145    }
146
147    /**
148     * Check if Vite manifest exists (build has been run)
149     *
150     * @return bool
151     */
152    public static function isBuildAvailable(): bool
153    {
154        return file_exists(self::getManifestPath());
155    }
156}