You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**State als Properties ablegen** (werden im Web automatisch zwischen Steps gespeichert)
24
+
-**Store state as public properties**
25
+
(they are automatically persisted between steps in the web flow)
26
+
22
27
```php
23
28
public ?string $environment = null;
24
29
public ?string $projectName = null;
25
30
```
26
31
27
-
-**Steps über `promptFlowSteps()` definieren** – Reihenfolge = Flow-Reihenfolge
32
+
-**Define steps via `promptFlowSteps()`** – the array order **is the flow order**
33
+
28
34
```php
29
35
public function promptFlowSteps(): array
30
36
{
@@ -37,17 +43,18 @@ Damit ein Command sowohl in der CLI als auch im Web korrekt als Flow funktionier
37
43
}
38
44
```
39
45
40
-
-**Jeder Step ist eine `public function stepXyz(): void`** – idealerweise **ein Prompt pro Step**
46
+
-**Each step is a `public function stepXyz(): void`** – ideally **one prompt per step**
47
+
41
48
```php
42
49
public function stepIntro(): void
43
50
{
44
-
$this->info('=== Projekt Setup ===');
51
+
$this->info('=== Project Setup ===');
45
52
}
46
53
47
54
public function stepEnvironment(): void
48
55
{
49
56
$this->environment = select(
50
-
label: 'Welche Umgebung konfigurierst du?',
57
+
label: 'Which environment do you want to configure?',
51
58
options: [
52
59
'local' => 'Local',
53
60
'staging' => 'Staging',
@@ -60,42 +67,44 @@ Damit ein Command sowohl in der CLI als auch im Web korrekt als Flow funktionier
60
67
public function stepProjectName(): void
61
68
{
62
69
$this->projectName = text(
63
-
label: 'Wie heißt dein Projekt?',
64
-
placeholder: 'z.B. MyCoolApp',
70
+
label: 'What is your project name?',
71
+
placeholder: 'e.g. MyCoolApp',
65
72
validate: 'required|min:3',
66
73
required: true,
67
74
);
68
75
}
69
76
70
77
public function stepSummary(): void
71
78
{
72
-
$this->info('--- Zusammenfassung ---');
73
-
$this->line('Projekt: '.$this->projectName);
79
+
$this->info('--- Summary ---');
80
+
$this->line('Project: '.$this->projectName);
74
81
$this->line('Environment: '.$this->environment);
75
82
}
76
83
}
77
84
```
78
85
79
-
-**Optionale Steps** kannst du einfach mit einem Guard am Anfang überspringen:
86
+
-**Optional steps** can simply be skipped with a guard at the beginning:
87
+
80
88
```php
81
89
public array $features = [];
82
90
83
91
public function stepLoggingLevel(): void
84
92
{
85
93
if (! in_array('logging', $this->features, true)) {
86
-
return; // Step wird übersprungen
94
+
return; // skip step
87
95
}
88
96
89
97
// Prompt …
90
98
}
91
99
```
92
100
93
-
-**Andere Artisan-Commands aufrufen** – verwende im Flow immer `$this->call()` statt `Artisan::call()`, damit der Output auch im Web angezeigt wird:
101
+
-**Calling other Artisan commands** – in a flow, always use `$this->call()` instead of `Artisan::call()`, so the output is also visible in the web UI:
102
+
94
103
```php
95
104
public function stepPublishConfig(): void
96
105
{
97
106
$shouldPublish = confirm(
98
-
label: 'Möchtest du die Config jetzt veröffentlichen?',
107
+
label: 'Publish the config now?',
99
108
default: true,
100
109
);
101
110
@@ -109,131 +118,201 @@ Damit ein Command sowohl in der CLI als auch im Web korrekt als Flow funktionier
109
118
}
110
119
```
111
120
112
-
Mehr ist im Command nicht nötig – keine speziellen Flow-Methoden, keine eigene Persistenz.
113
-
Der Rest (CLI/Web-Unterschied, State, Web-Oberfläche) wird komplett vom Package übernommen.
121
+
That’s all you need in the command – no special flow methods, no custom persistence.
122
+
Everything else (CLI/Web differences, state, web UI) is handled by the package.
114
123
115
-
## Ausführung im Browser (Filament)
124
+
## Running flows in the browser (Filament)
116
125
117
-
Nachdem du einen Flow-Command erstellt hast, kannst du ihn sowohl in der CLI als auch im Browser ausführen:
126
+
Once you’ve created a flow command, you can run it in both CLI and browser.
118
127
119
-
### CLI-Ausführung
128
+
### CLI
120
129
121
130
```bash
122
131
php artisan prompts:project-setup
123
132
```
124
133
125
-
Der Command läuft wie ein normaler Laravel Artisan Command – alle Prompts werden direkt im Terminal angezeigt.
134
+
The command behaves like a normal Laravel Artisan command – all prompts are shown in the terminal.
126
135
127
-
### Web-Ausführung
136
+
### Web
128
137
129
-
1.Öffne die Filament-Seite "Run Command" (wird automatisch im Navigation-Menü angezeigt)
130
-
2.Wähle einen Flow-Command aus der Liste
131
-
3.Klicke auf "Command starten"
132
-
4.Der Flow läuft Schritt für Schritt im Browser ab:
133
-
-Jeder Step zeigt einen Prompt (Text-Input, Select, Multiselect, Confirm, etc.)
134
-
-Nach jedem Step siehst du den Output des Steps
135
-
-Du kannst jederzeit mit "Zurück zur Command-Auswahl" abbrechen
136
-
-Nach erfolgreichem Abschluss wird der Button zu "Start new command" geändert
138
+
1.Open the Filament page **“Run Command”** (automatically added to navigation)
139
+
2.Select your flow command from the list
140
+
3.Click **“Start command”**
141
+
4.The flow runs step by step in the browser:
142
+
-Every step shows a prompt (text, select, multiselect, confirm, etc.)
143
+
-After each step you see the step’s output
144
+
-You can cancel any time with “Back to command selection”
145
+
-After a successful run the button switches to “Start new command”
137
146
138
-
**Wichtig:**Alle Commands, die im Web ausgeführt werden, werden automatisch in der Datenbank geloggt (siehe[Command Execution Logging](#command-execution-logging)).
147
+
**Note:**All commands executed via the web UI are automatically logged in the database (see[Command Execution Logging](#command-execution-logging)).
139
148
140
-
## Wie und warum wird Reflection verwendet?
149
+
## How and why reflection is used
141
150
142
-
Wenn du nur Commands schreibst, musst du dich nicht um Reflection kümmern.
143
-
Damit du aber verstehst, was im Hintergrund passiert, hier eine kurze Erklärung.
151
+
If you’re just writing commands, you don’t need to care about reflection.
152
+
To understand what happens under the hood, here’s a short overview.
144
153
145
-
-**Problem 1: Argumente & Optionen im Web setzen**
146
-
Laravel speichert Argumente/Optionen intern in einem geschützten Property `$input`deines Commands.
147
-
In der CLI kümmert sich der Artisan-Kernel darum, dieses Property zu setzen.
148
-
Im Web-Flow erzeugen wir aber selbst neue Command-Instanzen – und müssen `$input`daher manuell setzen.
149
-
Genau das macht `PromptFlowRunner::setCommandInput()`mit Reflection:
150
-
-es findet das `input`-Property auf deinem Command-Objekt,
151
-
-macht es kurz zugänglich,
152
-
-und schreibt das aktuelle Input-Objekt hinein.
153
-
**Ergebnis:** In Flow-Commands kannst du überall ganz normal`argument()`und`option()`verwenden – egal ob der Command per CLI oder im Browser läuft.
154
+
-**Problem 1: Setting arguments & options in the web flow**
155
+
Laravel stores arguments/options internally on a protected `$input`property of your command.
156
+
In CLI mode the Artisan kernel takes care of this.
157
+
In the web flow, we create fresh command instances – and need to set `$input`ourselves.
158
+
That’s what `PromptFlowRunner::setCommandInput()`does via reflection:
159
+
-finds the `input` property on your command object,
160
+
-temporarily makes it accessible,
161
+
-assigns the current `ArrayInput` instance.
162
+
**Result:** In flow commands you can keep using`argument()`and`option()`normally – both in CLI and in the browser.
154
163
155
-
-**Problem 2: Command-State zwischen Web-Requests merken**
156
-
Im Web besteht dein Flow aus mehreren HTTP-Requests. Ohne zusätzliche Logik wären Properties wie `$environment`, `$features`, `$projectName`im nächsten Step einfach weg.
157
-
`PromptFlowRunner`löst das mit zwei internen Methoden:
164
+
-**Problem 2: Remembering command state between web requests**
165
+
In the web flow, your command runs across multiple HTTP requests. Without extra logic, properties like `$environment`, `$features`, `$projectName`would be lost between steps.
166
+
`PromptFlowRunner`handles this with two internal methods:
158
167
-`captureCommandContext($command, $state)`
159
-
-liest per Reflection alle nicht-statischen Properties deiner konkreten Command-Klasse aus
-setzt beim nächsten Request alle gespeicherten Werte wieder zurück auf das neue Command-Objekt
163
-
**Ergebnis:**Für deinen Code fühlt es sich so an, als würde derselbe Command einfach weiterlaufen – du musst keine eigene Persistenz (Cache, Datenbank, Session, …) schreiben.
171
+
-restores all stored values back onto the new command instance on the next request
172
+
**Result:**For your code it feels like the same command instance keeps running – you don’t need your own persistence layer (cache, DB, session, …).
164
173
165
-
-**Problem 3: Package-Tools im Web initialisieren**
166
-
Viele Packages, die`Spatie\LaravelPackageTools`verwenden, registrieren ihre publishable Ressourcen (Config, Views, Migrations, Assets, …) nur im CLI-Kontext.
167
-
`WebCommandRunner`verwendet Reflection, um intern an das`package`-Objekt eines solchen Service Providers zu kommen und die `publishes(...)`-Registrierung auch im Web nachzuholen.
168
-
**Ergebnis:**Befehle wie`vendor:publish`funktionieren im Browser genauso zuverlässig wie in der CLI, obwohl Laravel dort eigentlich nicht im Console-Modus läuft.
174
+
-**Problem 3: Initializing package tools in the web context**
175
+
Many packages using`Spatie\LaravelPackageTools`only register publishable resources (config, views, migrations, assets, …) in CLI context.
176
+
`WebCommandRunner`uses reflection to access the internal`package` object and replay `publishes(...)` registrations for the web context.
177
+
**Result:**Commands like`vendor:publish`work just as well in the browser as in CLI, even though Laravel is not running in console mode there.
169
178
170
-
**Wichtig:**
171
-
Reflection wird nur in diesen internen Klassen des Packages verwendet, nicht in deinen Commands.
172
-
Deine Commands bleiben normale Laravel-Commands – du musst nur:
179
+
**Important:**
180
+
Reflection is only used inside the package internals, not in your flow commands.
181
+
Your commands remain normal Laravel commands – you only need to:
173
182
174
-
-von`FlowCommand` erben,
175
-
-Properties für den State definieren,
176
-
-Steps in `promptFlowSteps()` auflisten,
177
-
-`step*`-Methoden schreiben (am besten ein Prompt pro Step).
183
+
-extend`FlowCommand`,
184
+
-define properties for your state,
185
+
-list steps in `promptFlowSteps()`,
186
+
-implement `step*` methods (ideally one prompt per step).
178
187
179
-
Den Rest (Reflection, State, Web-Flow) übernimmt das Package für dich.
188
+
The package takes care of the rest (reflection, state, web flow).
180
189
181
-
### Gibt es Alternativen ohne Reflection?
190
+
### Are there alternatives without reflection?
182
191
183
-
Ja – theoretisch könnten wir auf Reflection verzichten, aber das hätte Nachteile für dich als Nutzer:
192
+
Yes – technically we could avoid reflection, but it would degrade the DX:
184
193
185
-
-Für**Argumente & Optionen**könnten wir eine eigene API einführen (statt`argument()/option()`), oder erzwingen, dass du alles manuell über Properties/Arrays verwaltest. Das wäre weniger “Laravel-typisch” und schwerer zu verstehen.
186
-
-Für den **Command-State zwischen Steps**könnten wir dich z.B. eine Methode wie `flowContextKeys()` implementieren lassen, in der du alle zu speichernden Properties auflistest, oder dich zwingen, selbst Cache/DB/Session zu benutzen. Das wäre mehr Boilerplate und eine zusätzliche Fehlerquelle.
187
-
-Für**Spatie Package Tools im Web**bräuchten wir entweder Änderungen im Spatie-Package selbst oder eine eigene, manuelle Konfiguration aller publishbaren Pfade – beides würde die Einrichtung deutlich komplizierter machen.
194
+
-For**arguments & options**we’d need a custom API instead of`argument()/option()`, or force you to manage everything via properties/arrays. That’s less “Laravel-ish” and harder to learn.
195
+
-For **state between steps**we could ask you to manually list all properties to persist (e.g. `flowContextKeys()`), or manage cache/DB/session yourself. That’s more boilerplate and error-prone.
196
+
-For**Spatie Package Tools in the web**we’d either need changes in the Spatie package or manual configuration of all publishable paths – both would make setup more complex.
188
197
189
-
Aus diesen Gründen kapseln wir die Reflection-Nutzung bewusst im Package und halten die API für deine Commands so einfach wie möglich.
198
+
That’s why we intentionally keep reflection encapsulated in the package and keep your command API as simple as possible.
190
199
191
200
## Command Execution Logging
192
201
193
-
Alle Commands, die über das Web-Interface ausgeführt werden, werden automatisch in der Datenbank geloggt. Du kannst die Ausführungen in der Filament-Resource "Command Executions" einsehen.
202
+
All commands executed via the web interface are automatically logged in the database.
203
+
You can inspect them via the Filament resource **“Command Executions”**.
194
204
195
205
### Status
196
206
197
-
Jede Command-Ausführung hat einen der folgenden Status:
207
+
Each execution has one of the following statuses:
208
+
209
+
-**`running`**: The command is currently running
210
+
-**`completed`**: The command finished successfully
211
+
-**`failed`**: The command failed with an error
212
+
-**`cancelled`**: The command was cancelled by the user or aborted mid-flow
0 commit comments