From 3413da6cf6c9900343f00363032b7f75a488ccef Mon Sep 17 00:00:00 2001 From: Ben Croker Date: Fri, 3 Jan 2025 19:59:43 -0600 Subject: [PATCH] Config and refactoring --- config/datastar.php | 2 +- phpstan.neon | 1 + src/DatastarServiceProvider.php | 44 ++++++++++++------- src/Http/Controllers/DatastarController.php | 12 +++-- src/Models/{ConfigModel.php => Config.php} | 9 ++-- src/Models/{SignalsModel.php => Signals.php} | 17 ++++--- src/Services/SseService.php | 28 +++++------- .../DatastarVariable.php} | 27 +++++++++--- 8 files changed, 80 insertions(+), 60 deletions(-) rename src/Models/{ConfigModel.php => Config.php} (93%) rename src/Models/{SignalsModel.php => Signals.php} (90%) rename src/{Globals/DatastarGlobal.php => Variables/DatastarVariable.php} (70%) diff --git a/config/datastar.php b/config/datastar.php index 34e5d71..beb511e 100644 --- a/config/datastar.php +++ b/config/datastar.php @@ -18,7 +18,7 @@ * The event options to override the Datastar defaults. Null values will be ignored. */ 'defaultEventOptions' => [ - 'retryDuration' => null, + 'retryDuration' => 123, ], /** diff --git a/phpstan.neon b/phpstan.neon index 91e6453..bf455e9 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,3 +2,4 @@ parameters: level: 5 paths: - src + - config diff --git a/src/DatastarServiceProvider.php b/src/DatastarServiceProvider.php index 026e13d..efb1fcd 100644 --- a/src/DatastarServiceProvider.php +++ b/src/DatastarServiceProvider.php @@ -9,63 +9,77 @@ use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; -use Putyourlightson\Datastar\Globals\DatastarGlobal; use Putyourlightson\Datastar\Http\Controllers\DatastarController; use Putyourlightson\Datastar\Services\SseService; +use Putyourlightson\Datastar\Variables\DatastarVariable; class DatastarServiceProvider extends ServiceProvider { - /** - * @inheritdoc - */ public function register(): void { + $this->mergeConfigFrom(__DIR__ . '/../config/datastar.php', 'datastar'); + $this->app->singleton(SseService::class, function() { return new SseService(); }); } - /** - * Bootstrap services. - */ public function boot(): void + { + $this->registerRoutes(); + $this->registerVariables(); + $this->registerDirectives(); + } + + protected function registerRoutes(): void { Route::match( ['get', 'post', 'put', 'patch', 'delete'], '/datastar-controller', [DatastarController::class, 'index'], ); + } + protected function registerVariables(): void + { View::composer('*', function(\Illuminate\View\View $view) { - $view->with('datastar', new DatastarGlobal(app(SseService::class))); + $view->with('datastar', new DatastarVariable(app(SseService::class))); }); + } + protected function registerDirectives(): void + { Blade::directive('mergefragments', function(string $expression) { - return "setSseInProcess('mergeFragments', $expression); ob_start(); ?>"; + return $this->getDirective("setSseInProcess('mergeFragments', $expression); ob_start()"); }); Blade::directive('endmergefragments', function() { - return "mergeFragments(ob_get_clean()); ?>"; + return $this->getDirective("mergeFragments(ob_get_clean())"); }); Blade::directive('removefragments', function(string $expression) { - return "removeFragments($expression); ?>"; + return $this->getDirective("removeFragments($expression)"); }); Blade::directive('mergesignals', function(string $expression) { - return "mergeSignals($expression); ?>"; + return $this->getDirective("mergeSignals($expression)"); }); Blade::directive('removesignals', function(string $expression) { - return "removeSignals($expression); ?>"; + return $this->getDirective("removeSignals($expression)"); }); Blade::directive('executescript', function(string $expression) { - return "setSseInProcess('executeScript', $expression); ob_start(); ?>"; + return $this->getDirective("setSseInProcess('executeScript', $expression); ob_start()"); }); Blade::directive('endexecutescript', function() { - return "executeScript(ob_get_clean()); ?>"; + return $this->getDirective("executeScript(ob_get_clean())"); }); } + + protected function getDirective(string $expression): string + { + return "$expression ?>"; + } } diff --git a/src/Http/Controllers/DatastarController.php b/src/Http/Controllers/DatastarController.php index 80bfb15..2a19b13 100644 --- a/src/Http/Controllers/DatastarController.php +++ b/src/Http/Controllers/DatastarController.php @@ -13,11 +13,9 @@ class DatastarController extends Controller { - protected SseService $sse; - - public function __construct(SseService $sse) - { - $this->sse = $sse; + public function __construct( + protected SseService $sse, + ) { } public function index(Request $request): StreamedResponse @@ -27,8 +25,8 @@ public function index(Request $request): StreamedResponse if (strtolower($request->header('Content-Type')) === 'application/json') { // Clear out params to prevent them from being processed by controller actions. -// $request->setQueryParams([]); -// $request->setBodyParams([]); + $request->query->replace(); + $request->request->replace(); } // Set the response headers for the event stream. diff --git a/src/Models/ConfigModel.php b/src/Models/Config.php similarity index 93% rename from src/Models/ConfigModel.php rename to src/Models/Config.php index f504ce3..2fde2e0 100644 --- a/src/Models/ConfigModel.php +++ b/src/Models/Config.php @@ -9,10 +9,10 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Validation\ValidationException; -class ConfigModel +class Config { - protected const HASH_LENGTH = 64; protected const HASH_ALGORITHM = 'sha256'; + protected const HASH_LENGTH = 64; public string $view = ''; public array $variables = []; @@ -20,7 +20,7 @@ class ConfigModel public ?string $csrfToken = null; /** - * Creates a new instance from an encrypted config string. + * Creates a new instance from a hashed config string. */ public static function fromHashed(string $config): ?self { @@ -102,8 +102,7 @@ public function validate(): void */ protected function validateVariables(string $attribute, mixed $variables, Closure $fail): void { -// $signalsVariableName = Datastar::getInstance()->settings->signalsVariableName; - $signalsVariableName = 'signals'; + $signalsVariableName = config('datastar.signalsVariableName'); foreach ($variables as $key => $value) { if ($key === $signalsVariableName) { diff --git a/src/Models/SignalsModel.php b/src/Models/Signals.php similarity index 90% rename from src/Models/SignalsModel.php rename to src/Models/Signals.php index c94b1cb..9801829 100644 --- a/src/Models/SignalsModel.php +++ b/src/Models/Signals.php @@ -7,13 +7,12 @@ use Putyourlightson\Datastar\Services\SseService; -class SignalsModel +class Signals { - private array $values; - - public function __construct(array $values) - { - $this->values = $values; + public function __construct( + protected array $values, + protected SseService $sse, + ) { } public function __get(string $name) @@ -56,7 +55,7 @@ public function set(string $name, mixed $value): static { $this->setNestedValue($name, $value); - app(SseService::class)->mergeSignals($this->getNestedArrayValue($name, $value)); + $this->sse->mergeSignals($this->getNestedArrayValue($name, $value)); return $this; } @@ -70,7 +69,7 @@ public function setValues(array $values): static $this->values[$name] = $value; } - app(SseService::class)->mergeSignals($values); + $this->sse->mergeSignals($values); return $this; } @@ -82,7 +81,7 @@ public function remove(string $name): static { $this->removeNestedValue($name); - app(SseService::class)->removeSignals([$name]); + $this->sse->removeSignals([$name]); return $this; } diff --git a/src/Services/SseService.php b/src/Services/SseService.php index 5ed0c29..8cfeef1 100644 --- a/src/Services/SseService.php +++ b/src/Services/SseService.php @@ -7,8 +7,8 @@ use Illuminate\Validation\ValidationException; use Putyourlightson\Datastar\Http\Controllers\DatastarController; -use Putyourlightson\Datastar\Models\ConfigModel; -use Putyourlightson\Datastar\Models\SignalsModel; +use Putyourlightson\Datastar\Models\Config; +use Putyourlightson\Datastar\Models\Signals; use starfederation\datastar\ServerSentEventGenerator; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Throwable; @@ -52,7 +52,7 @@ public function getAction(string $method, string $view, array $variables, array public function getUrl(string $method, string $view, array $variables = []): string { - $config = new ConfigModel([ + $config = new Config([ 'view' => $view, 'variables' => $variables, 'includeCsrfToken' => $method !== 'get', @@ -72,13 +72,11 @@ public function getUrl(string $method, string $view, array $variables = []): str /** * Merges HTML fragments into the DOM. - * - * @used-by FragmentNode */ public function mergeFragments(string $data, array $options = []): void { $options = $this->mergeEventOptions( - config('datastar.defaultFragmentOptions') ?? [], + config('datastar.defaultFragmentOptions', []), $options, ); @@ -91,7 +89,7 @@ public function mergeFragments(string $data, array $options = []): void public function removeFragments(string $selector, array $options = []): void { $options = $this->mergeEventOptions( - config('datastar.defaultFragmentOptions') ?? [], + config('datastar.defaultFragmentOptions', []), $options, ); @@ -104,7 +102,7 @@ public function removeFragments(string $selector, array $options = []): void public function mergeSignals(array $signals, array $options = []): void { $options = $this->mergeEventOptions( - config('datastar.defaultSignalOptions') ?? [], + config('datastar.defaultSignalOptions', []), $options, ); @@ -121,13 +119,11 @@ public function removeSignals(array $paths, array $options = []): void /** * Executes JavaScript in the browser. - * - * @used-by ExecuteScriptNode */ public function executeScript(string $script, array $options = []): void { $options = $this->mergeEventOptions( - config('datastar.defaultExecuteScriptOptions') ?? [], + config('datastar.defaultExecuteScriptOptions', []), $options, ); @@ -148,15 +144,14 @@ public function setSseInProcess(string $method, array $options = []): void */ public function stream(string $config, array $signals): void { - $config = ConfigModel::fromHashed($config); + $config = Config::fromHashed($config); if ($config === null) { $this->throwException('Submitted data was tampered.'); } - $signals = new SignalsModel($signals); + $signals = new Signals($signals, $this); $variables = array_merge( - //[Datastar::getInstance()->settings->signalsVariableName => $signals], - ['signals' => $signals], + [config('datastar.signalsVariableName', 'signals') => $signals], $config->variables, ); @@ -168,7 +163,8 @@ public function stream(string $config, array $signals): void */ private function mergeEventOptions(array ...$optionSets): array { - $options = array_merge([], //Datastar::getInstance()->settings->defaultEventOptions; + $options = array_merge( + config('datastar.defaultEventOptions', []), $this->sseOptionsInProcess, ); diff --git a/src/Globals/DatastarGlobal.php b/src/Variables/DatastarVariable.php similarity index 70% rename from src/Globals/DatastarGlobal.php rename to src/Variables/DatastarVariable.php index e74cd8c..8978ecd 100644 --- a/src/Globals/DatastarGlobal.php +++ b/src/Variables/DatastarVariable.php @@ -3,39 +3,52 @@ * @copyright Copyright (c) PutYourLightsOn */ -namespace Putyourlightson\Datastar\Globals; +namespace Putyourlightson\Datastar\Variables; use Putyourlightson\Datastar\Services\SseService; -class DatastarGlobal +class DatastarVariable { - private SseService $sse; - - public function __construct(SseService $sse) - { - $this->sse = $sse; + public function __construct( + protected SseService $sse, + ) { } + /** + * Returns a Datastar `@get` action. + */ public function get(string $view, array $variables = [], array $options = []): string { return $this->sse->getAction('get', $view, $variables, $options); } + /** + * Returns a Datastar `@post` action. + */ public function post(string $view, array $variables = [], array $options = []): string { return $this->sse->getAction('post', $view, $variables, $options); } + /** + * Returns a Datastar `@put` action. + */ public function put(string $view, array $variables = [], array $options = []): string { return $this->sse->getAction('put', $view, $variables, $options); } + /** + * Returns a Datastar `@patch` action. + */ public function patch(string $view, array $variables = [], array $options = []): string { return $this->sse->getAction('patch', $view, $variables, $options); } + /** + * Returns a Datastar `@delete` action. + */ public function delete(string $view, array $variables = [], array $options = []): string { return $this->sse->getAction('delete', $view, $variables, $options);