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
{{ message }}
Repository navigation
Commit f77eafc
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: public/frontend.md
+20-19Lines changed: 20 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ Web starter . Server-rendered
12
12
A web starter skeleton on the Mezzio microframework and Laminas components, for the applications people log into.
13
13
User accounts, a working contact form and a content page ship as proof of concept - real, running features whose only job is to show you where your own code goes.
14
14
15
-
-[Read the docs](https://docs.dotkernel.org/frontend/)
15
+
-[Read the docs](https://docs.dotkernel.org/frontend-documentation/)
16
16
-[View on GitHub](https://github.com/dotkernel/frontend)
17
17
-[Live demo](https://v5.dotkernel.net/)
18
18
@@ -24,7 +24,7 @@ User accounts, a working contact form and a content page ship as proof of concep
@@ -36,7 +36,7 @@ They exist to showcase the file architecture and to be copied.
36
36
37
37
Extending the power of Mezzio by Laminas.
38
38
39
-
- User accounts, from register to unregister
39
+
- User accounts, from registration to account deletion
40
40
- Action controllers, not request handlers
41
41
- CSRF and reCAPTCHA on public forms
42
42
- GDPR anonymization out of the box
@@ -49,8 +49,8 @@ These are the parts you would otherwise spend your first two weeks assembling, a
49
49
50
50
The whole account lifecycle, already routed.
51
51
52
-
Login, registration and account management, including avatar upload, password change and unregistering.
53
-
Password reset and account activation emails are part of the flow, which is why the skeleton stores a name and an email address and nothing more.
52
+
Login, registration and account management, including activation, password reset, avatar upload, profile details, password change and account deletion.
53
+
Password reset and account activation emails are part of the flow, which is why the only personal details on a user profile are a name and an email address.
54
54
55
55
### Guards per action - Security . Access control
56
56
@@ -70,8 +70,8 @@ Tokens expire after a configurable timeout - one hour by default - and are never
70
70
71
71
A public form that does not become a spam relay.
72
72
73
-
The contact form uses Google reCAPTCHA, with the site and secret keys read from local configuration and the message recipients - `to`and any number of `cc` addresses - configured alongside them.
74
-
Whitelist`localhost` while developing, and take it out again for production.
73
+
The contact form uses score-based Google reCAPTCHA, with the site key, secret key and score threshold read from local configuration, and the message recipients - `to`, `cc`and `bcc` addresses - configured alongside them.
74
+
The contact page will not render until the keys are set; whitelist`localhost` while developing, and take it out again for production.
75
75
76
76
### Flash messages - UX . Feedback
77
77
@@ -96,9 +96,9 @@ Migrations live in `data/doctrine/migrations`; `bin/doctrine fixtures:execute` s
96
96
97
97
### Headers & CORS - Delivery . HTTP
98
98
99
-
Response headers declared per route.
99
+
Response headers declared globally or per route.
100
100
101
-
`dot-response-header` sets custom headers per route from `response-header.global.php`, while `mezzio-cors` handles origins, headers and cookies from `cors.global.php`.
101
+
`dot-response-header` sets custom headers for all routes or for individual routes from `response-header.global.php`, while `mezzio-cors` handles origins, headers and cookies from `cors.global.php`.
@@ -113,16 +113,17 @@ The `Plugin` module carries dynamic forms and templates.
113
113
Under the GDPR, a company recording personal data from EU citizens must delete it on request - or anonymize it, which the European Commission accepts as an alternative.
114
114
Frontend implements the second option, because deleting a user row is rarely what your foreign keys want.
115
115
116
-
The skeleton stores only what it needs to run those flows: first name, last name and the email address used as the identity, for password reset and account activation.
117
-
Anonymizing replaces exactly those.
116
+
On the user profile, the skeleton stores only what it needs to run those flows: first name, last name and the email address used as the identity, for password reset and account activation.
117
+
Anonymizing replaces exactly those; contact form messages and remember-me records are kept as they are.
- First and last name become `anonymous` plus the current UNIX timestamp - for example `anonymous1725980747`.
124
-
- The email becomes the same value plus whatever you set in `userAnonymizeAppend` - `anonymous1725980747@example.com`.
125
-
- The avatar image and its database record are deleted.
123
+
- First and last name become `anonymous` plus the current date and time in `dmYHis` format - for example `anonymous23092026155300`.
124
+
- The email becomes the same value plus whatever you set in `userAnonymizeAppend` - `anonymous23092026155300@example.com`.
125
+
- The account status is set to `deleted`; the row itself is kept.
126
+
- On account deletion, the avatar image and its database record are deleted.
126
127
127
128
Point `userAnonymizeAppend` at a domain you control and it doubles as a catch-all address, if your mail provider supports one.
128
129
Leave it empty and the local part stands alone.
@@ -153,7 +154,7 @@ Plugin functionality for dynamic forms and templates.
153
154
154
155
### Module contents
155
156
156
-
`Controller`, `Entity`, `Repository` and `Service` folders, plus `InputFilter`, `EventListener`, `Helper`, `Command` or `Factory` as needed.
157
+
`Controller`, `Entity`, `Repository` and `Service` folders, plus `Form`, `Fieldset`, `InputFilter`, `EventListener`, `Factory`, `Middleware` or `Enum` as needed.
157
158
158
159
## From clone to welcome page
159
160
@@ -187,7 +188,7 @@ composer development-enable
187
188
188
189
### 4 . Prepare the config files
189
190
190
-
Copy the `.dist` files into place - `local.php`, `development.local.php`, `mail.local.php`, `debugbar.local.php`- then fill in the database, SMTP and reCAPTCHA details.
191
+
`composer install` has already created `local.php` and `mail.global.php`, and development mode created `development.local.php`; fill in the database and reCAPTCHA details in `local.php`, and copy `mail.global.php` to `mail.local.php`for the sender and SMTP details, so credentials stay out of git.
191
192
192
193
### 5 . Migrate and seed
193
194
@@ -214,11 +215,11 @@ Duplicating `local.test.php.dist` gives your tests an in-memory database.
214
215
| Component | Requirement |
215
216
| --- | --- |
216
217
| Operating system | A \*nix based system is strongly recommended for production. |
217
-
| PHP | 8.2 or newer, mod_php or FCGI (FPM). `memory_limit` at least 128M; `upload_max_filesize` and `post_max_size` at least 100M depending on your data. |
218
+
| PHP | 8.2 or 8.3, mod_php or FCGI (FPM). `memory_limit` at least 128M; `upload_max_filesize` and `post_max_size` at least 100M depending on your data. |
218
219
| Web server | Apache 2.2+ with `mod_rewrite` and `.htaccess` support (`AllowOverride All`); a default `.htaccess` ships in `public/`. On Nginx, translate it into server configuration. |
219
220
| Database | Tested with MariaDB 10.11 LTS and 11.4 LTS, and with MySQL 8.4 LTS. For MySQL 8.4, `my.cnf` needs `mysql_native_password=ON`. |
220
-
| Required extensions |`mbstring`, the CLI SAPI for cron jobs, and Composer on `$PATH`. |
221
-
| Recommended extensions |`opcache`; `pdo_mysql` or `mysqli`; `dom` and `simplexml` for markup; `gd` and `exif` for images; `zlib`, `zip`, `bz2` for compression; `curl` when calling APIs; `sqlite3` for the test suite. |
221
+
| Required extensions |`curl`, `gettext`, `intl`, `json`, `mbstring`, the CLI SAPI for cron jobs, and Composer on `$PATH`. |
222
+
| Recommended extensions |`opcache`; `pdo_mysql`for MySQL or MariaDB; `dom` and `simplexml` for markup; `gd` and `exif` for images; `zlib`, `zip`, `bz2` for compression; `sqlite3` for the test suite. |
222
223
223
224
Note that Frontend still supports MySQL - unlike API and Admin v7, which require native UUID support and therefore PostgreSQL or MariaDB 10.7+.
Copy file name to clipboardExpand all lines: public/light.md
+16-29Lines changed: 16 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -134,7 +134,7 @@ One command while you work, one before you ship.
134
134
135
135
Vite concatenates and compresses CSS and JavaScript, preprocesses SCSS, and copies fonts and images - avoiding the network bottleneck of many separate files.
136
136
`npm run watch` recompiles on change; `npm run build` compiles once.
137
-
Node.js v20 is the minimum supported version.
137
+
Node.js `^20.19.0` or `>=22.12.0` is required.
138
138
139
139
### assets -> public - Build . Source of truth
140
140
@@ -174,56 +174,43 @@ Development mode adds the error handlers you want locally and nowhere else.
174
174
## Running in minutes, honestly
175
175
176
176
No database to create, no fixtures to seed.
177
-
Clone, install, set a URL, open it.
177
+
Create the project, set a URL, open it.
178
178
179
-
### 1 . Clone into an empty folder
179
+
### 1 . Create the project
180
180
181
-
Git refuses a directory that is not empty, and you need write permissions on it.
181
+
One Composer command creates the directory, installs dependencies, and enables development mode for you.
Decline the config provider injection when prompted - Light already includes its own.
188
189
189
-
Run it from the CLI so the prompts stay interactive.
190
-
Decline the config provider injection - Light already includes its own.
191
-
192
-
```shell
193
-
composer install
194
-
```
195
-
196
-
### 3 . Enable development mode
197
-
198
-
Local work only.
199
-
`composer development-status` reports where you stand.
200
-
201
-
```shell
202
-
composer development-enable
203
-
```
204
-
205
-
### 4 . Set the base URL
190
+
### 2 . Set the base URL
206
191
207
192
Point `$baseUrl` in `config/autoload/local.php` at your virtual host.
208
193
209
-
### 5 . Fix the writable folders
194
+
### 3 . Fix the writable folders
210
195
211
196
The two directories the application writes to.
212
-
Most first-run errors are this and nothing else.
197
+
Most first-run errors are this and nothing else. Give the web server group write access instead of opening the folders to everyone:
213
198
214
199
```shell
215
-
chmod -R 777 ./data ./log
200
+
sudo chown -R "$USER":www-data data log
201
+
sudo chmod -R 775 data log
216
202
```
217
203
218
-
### 6 . Open it in a browser
204
+
### 4 . Open it in a browser
219
205
220
206
The Dotkernel Light welcome page is waiting.
221
207
Errors about missing services usually mean a stale config cache.
222
208
223
209
```shell
224
-
php ./bin/clear-config-cache.php
210
+
composer clear-config-cache
225
211
```
226
212
213
+
Do not run this with `sudo` - that leaves the regenerated `data/cache/config-cache.php` owned by root, which the application can no longer rewrite.
227
214
A cached `data/cache/config-cache.php` is loaded regardless of the `ConfigAggregator::ENABLE_CACHE` setting - which is exactly why clearing it fixes so much.
228
215
On Windows, WSL2 with AlmaLinux is the recommended development environment.
229
216
@@ -232,7 +219,7 @@ On Windows, WSL2 with AlmaLinux is the recommended development environment.
232
219
| Component | Requirement |
233
220
| --- | --- |
234
221
| Operating system | A \*nix based system is strongly recommended for production. |
235
-
| PHP | 8.2, 8.3 or 8.4, with mod_php or FCGI (FPM). `memory_limit` at least 128M. |
222
+
| PHP | 8.3, 8.4 or 8.5, with mod_php or FCGI (FPM). `memory_limit` at least 128M. |
236
223
| Web server | Apache 2.2+ with `mod_rewrite` and `.htaccess` support (`AllowOverride All`); a default `.htaccess` ships in `public/`. On Nginx, translate it into server configuration. |
237
224
| Database | None. Light has no persistence layer - which is the point. |
238
225
| Required extensions |`mbstring`, plus Composer available on `$PATH`. |
0 commit comments