Skip to content

Commit 7b2fbed

Browse files
committed
Docs: Update upgrade notes for 0.8.0
1 parent a79ed2a commit 7b2fbed

4 files changed

Lines changed: 360 additions & 9 deletions

File tree

src/content/docs/getting-started/docker.mdoc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ Then open your server IP or hostname in a browser to complete the web installer.
3232
{% tabitem label="Docker Compose" %}
3333
This option brings up FOSSBilling and MySQL together, which makes it the fastest way to get started.
3434

35-
```yaml
36-
version: "3.9"
35+
```yaml {% meta="title='docker-compose.yml'" %}
3736
services:
3837
fossbilling:
3938
image: fossbilling/fossbilling:latest

src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc

Lines changed: 349 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ sidebar:
88
text: New
99
---
1010

11-
The 0.8.0 release includes significant database and structural changes. Read the notes below before upgrading.
11+
The 0.8.0 release includes significant database, structural, and frontend changes. Read every section below before upgrading.
12+
13+
{% aside type="caution" %}
14+
**Review custom themes and modules carefully.** 0.8.0 removes jQuery, switches from Webpack Encore to esbuild, replaces the routing layer with Symfony HttpKernel, and introduces multiple Twig filter removals and renames. Custom code that depends on the old infrastructure will break.
15+
{% /aside %}
16+
17+
## PHP Requirement
18+
19+
The minimum PHP version has been raised from 8.1 to **8.3**. Verify your server meets this requirement before upgrading.
1220

1321
## Database & Charset Migration
1422

@@ -19,6 +27,9 @@ The database charset has been migrated from `utf8` to `utf8mb4` / `utf8mb4_unico
1927
- `db.type` has been renamed to `db.driver` and its value changed from `'mysql'` to `'pdo_mysql'`. The patcher migrates this for you.
2028
- Old `api.rate_*` settings (`rate_span`, `rate_limit`, `throttle_delay`, `rate_span_login`, `rate_limit_login`, `rate_limit_whitelist`) have been replaced by the new `rate_limiter` block. The patcher will prompt you to accept the new defaults.
2129
- The `url` setting no longer stores the protocol prefix; it is stripped on save.
30+
- New `security.trusted_proxies` block for configuring reverse proxy trust.
31+
- New `security.session_regeneration_grace_period` setting (default: 300).
32+
- New `i18n.auto_detect_locale`, `i18n.date_format`, `i18n.time_format`, `i18n.datetime_pattern` settings.
2233

2334
## Module Migrations
2435

@@ -27,9 +38,11 @@ The following modules have been removed or replaced. The patcher handles the mig
2738
| Change | Details |
2839
|--------|---------|
2940
| `Servicemembership` removed | Membership products and orders are migrated to the "custom" product type. Review active membership orders after updating. |
30-
| `Spamchecker` replaced | Replaced by the new `Antispam` module (supports honeypot fields). Review your spam-protection settings after the update. |
31-
| `Wysiwyg` removed | Functionality replaced by built-in theme JavaScript. |
41+
| `Spamchecker` replaced | Replaced by the new `Antispam` module (supports Cloudflare Turnstile, hCaptcha, and honeypot fields). Review your spam-protection settings after the update. |
42+
| `Wysiwyg` removed | CKEditor 5 is now integrated directly into themes. Use the `wysiwyg` Twig function to initialize editors. |
3243
| `Paidsupport` removed | Module data is cleaned up. |
44+
| Added `Antispam` | New spam-prevention module with multiple challenge providers. |
45+
| Added `Widgets` | New module for registering renderable widget slots in templates. |
3346

3447
## Uploads Directory
3548

@@ -74,7 +87,339 @@ Shared browser assets now live in `/public` instead of `/data/assets` or theme-s
7487

7588
The patcher migrates bundled gateway icons and default branding settings automatically. If you maintain custom web-server rules, make sure `/public` remains publicly readable while `/data` remains blocked.
7689

77-
Custom themes should load shared frontend assets with `public_asset_url`, for example `{{ 'js/fossbilling.js'|public_asset_url|script_tag }}` followed by `{{ 'js/api.js'|public_asset_url|script_tag }}`. The old `library/Api/API.js` path has been removed.
90+
## Theme & Frontend Changes
91+
92+
### Build System: Webpack Encore → esbuild
93+
94+
The front-end build system has been migrated from [Webpack Encore](https://symfony.com/doc/current/frontend.html) to [esbuild](https://esbuild.github.io/).
95+
96+
- Bundled theme `package.json` scripts now call local `esbuild.mjs` files instead of Webpack Encore. Huraga's `dev` script uses `node ./esbuild.mjs --watch`; `admin_default` uses `node ./esbuild.mjs` for both `dev` and `build`.
97+
- Shared build helpers are in `frontend/tools/esbuild-helpers.mjs` (at the repository root).
98+
- Theme-specific build scripts are at `src/themes/{theme}/esbuild.mjs`.
99+
100+
If you maintain a custom theme with its own build pipeline, update it for the new asset structure and Twig loading pattern. You can keep another build tool if it outputs compatible assets, but the bundled `huraga` and `admin_default` themes now use esbuild and are the best reference implementations.
101+
102+
### Asset Loading
103+
104+
Replace `encore_entry_link_tags` / `encore_entry_script_tags` with direct CSS and JS asset tags:
105+
106+
{% tabs %}
107+
{% tabitem label="Before (0.7.x)" %}
108+
```twig
109+
{{ encore_entry_link_tags('fossbilling') }}
110+
{{ "Api/API.js" | library_url | script_tag }}
111+
{{ encore_entry_script_tags('fossbilling') }}
112+
```
113+
{% /tabitem %}
114+
{% tabitem label="After (0.8.0)" %}
115+
```twig
116+
<link rel="stylesheet" href="{{ 'build/css/vendor.css' | asset_url }}">
117+
<link rel="stylesheet" href="{{ 'build/css/fossbilling.css' | asset_url }}">
118+
{{ 'js/fossbilling.js' | public_asset_url | script_tag }}
119+
{{ 'js/api.js' | public_asset_url | script_tag }}
120+
<script src="{{ 'build/js/fossbilling.js' | asset_url }}"></script>
121+
```
122+
{% /tabitem %}
123+
{% /tabs %}
124+
125+
### jQuery Removed
126+
127+
jQuery has been removed from both bundled themes. All admin and client templates have been migrated to vanilla JavaScript.
128+
129+
- The old `bb` JavaScript object and `bb.redirect()` no longer exist. Use `window.location` instead.
130+
- `$(function() { ... })` → `document.addEventListener("DOMContentLoaded", function() { ... })`
131+
- Any custom theme or module JavaScript that depends on jQuery must be rewritten.
132+
133+
### JavaScript API Wrapper
134+
135+
The JS API wrapper has been rewritten and moved from `library/Api/API.js` to `frontend/core/api.js`. The browser call pattern (`API.admin.post`, `API.client.get`, `API.guest.get`, etc.) remains compatible, and the related Twig helpers (`fb_api_form`, `fb_api_link`) are still available, but the internal implementation is entirely new.
136+
137+
Load it with:
138+
```twig
139+
{{ 'js/fossbilling.js' | public_asset_url | script_tag }}
140+
{{ 'js/api.js' | public_asset_url | script_tag }}
141+
```
142+
143+
The old `library_url` filter used for `{{ "Api/API.js" | library_url | script_tag }}` has been removed.
144+
145+
### Frontend Directory Structure
146+
147+
Shared frontend source code has moved to a new `frontend/` directory at the repository root:
148+
149+
```
150+
frontend/
151+
├── core/
152+
│ ├── api.js # JavaScript API wrapper
153+
│ └── fossbilling.js # Runtime helpers (message toasts, request utilities)
154+
├── editor/
155+
│ └── ckeditor.js # CKEditor 5 bundle
156+
├── styles/
157+
│ └── markdown.css # Markdown content styling
158+
└── tools/
159+
└── esbuild-helpers.mjs # Shared build utilities
160+
```
161+
162+
### Debug Bar
163+
164+
The `DebugBar_renderHead()` Twig function has been renamed to `debug_bar_render_head()`:
165+
166+
{% tabs %}
167+
{% tabitem label="Before (0.7.x)" %}
168+
```twig
169+
{{ DebugBar_renderHead() }}
170+
```
171+
{% /tabitem %}
172+
{% tabitem label="After (0.8.0)" %}
173+
```twig
174+
{{ debug_bar_render_head() }}
175+
```
176+
{% /tabitem %}
177+
{% /tabs %}
178+
179+
### CSRF Meta Tag Removed
180+
181+
The `<meta name="csrf-token" content="{{ CSRFToken }}">` tag has been removed from bundled themes. CSRF tokens are now sent via cookie (`csrf_token`) and handled automatically by the JavaScript API wrapper. If your custom theme relies on the meta tag, switch to reading the cookie:
182+
183+
```javascript
184+
const token = document.cookie.match(/csrf_token=([^;]*)/)?.[1] || '';
185+
```
186+
187+
Build output is written to theme/public asset directories such as `src/public/assets`, not to a tracked `frontend/build` directory.
188+
189+
### Twig Globals
190+
191+
Available Twig globals to review when updating custom templates include:
192+
193+
| Global | Description |
194+
|--------|-------------|
195+
| `app_area` | `"admin"` or `"client"` |
196+
| `current_theme` | The active theme code |
197+
| `request` | Query parameters from the current request |
198+
| `request_query` | Original query parameters array |
199+
| `request_path` | Normalized route path |
200+
| `request_has_filters` | Boolean indicating active filters in the request |
201+
| `default_currency` | The default currency code |
202+
| `FOSSBillingVersion` | The current version string |
203+
204+
### Twig Filter Changes
205+
206+
The following filters have been **removed**:
207+
208+
| Removed filter | Replacement |
209+
|----------------|-------------|
210+
| `alink` | `url` with `area: 'admin'` — `{{ 'staff/login' \| url({area: 'admin'}) }}` |
211+
| `link` | `url` — `{{ 'order' \| url }}` |
212+
| `gravatar` | `avatar` function — `{{ avatar(email, 80) }}` (uses DiceBear locally) |
213+
| `library_url` | `public_asset_url` |
214+
| `markdown` | `markdown_to_html` — `{{ content \| markdown_to_html }}` |
215+
| `size` | `file_size` — `{{ 1048576 \| file_size }}` |
216+
| `number` | `format_number` (from Twig Intl Extra) |
217+
| `money` / `money_without_currency` | `format_currency` — `{{ 29.99 \| format_currency('USD') }}` |
218+
| `money_convert` / `money_convert_without_currency` | No direct Twig filter replacement. Convert the amount before rendering, then format it with `format_currency`. |
219+
| `img_tag` | Use standard `<img>` HTML |
220+
| `iplookup` | Removed. |
221+
| `ipcountryname` | Renamed to `ip_country_name` |
222+
| `autolink` | Removed. |
223+
224+
The following filters and functions have been **added**:
225+
226+
| New filter/function | Description |
227+
|---------------------|-------------|
228+
| `public_asset_url` | URL for shared core assets in `/public` |
229+
| `url` | Now accepts `area` parameter (`'admin'` / `'client'`) to replace both old `alink` and `link` |
230+
| `has_permission` | Check admin module permission in templates |
231+
| `render_widgets` | Render widgets for a named slot |
232+
| `svg_sprite` | Render the theme's SVG icon sprite |
233+
| `antispam_honeypot` | Return honeypot configuration array |
234+
| `wysiwyg` | Initialize CKEditor 5 on a textarea selector |
235+
| `avatar` | Generate DiceBear avatar image for an email address |
236+
| `script_tag` | Generate `<script>` tag with cache-busting hash |
237+
| `stylesheet_tag` | Generate `<link>` stylesheet tag with cache-busting hash |
238+
| `file_size` | Format bytes to human-readable size (replaces `size`) |
239+
| `hash` | Hash a value (defaults to xxh128) |
240+
| `api_url` | Supports `role` parameter to override the API area |
241+
242+
### Theme HTML Changes
243+
244+
Key template changes in both bundled themes (admin_default and huraga):
245+
246+
- `<html lang="en">` → `<html lang="{{ active_locale }}">` where `active_locale` is derived from the active locale.
247+
- `<meta property="bb:url">` and `<meta property="bb:client_area">` removed.
248+
- `<meta name="csrf-token">` removed (see CSRF section above).
249+
- `encore_entry_link_tags` / `encore_entry_script_tags` → direct asset links (see above).
250+
- Old admin redirect `bb.redirect(...)` → `window.location = ...`.
251+
- The `macro_functions.html.twig` import removed from layout files; macros are now loaded individually.
252+
- Language selectors use `js-locale-selector` class instead of `js-language-selector`.
253+
- New widget slots: `{{ render_widgets('client.theme.body.start') }}` in Huraga.
254+
- Dashboard cards rewritten with AJAX-loaded content.
255+
- Tables, pagination, forms, and search have been revamped with new markup and CSS.
256+
257+
## Guest API Lockdown
258+
259+
The guest API has been hardened to expose less information publicly:
260+
261+
- The guest `system/version` API action (`guest.system_version` in Twig) has been **removed** — versions are no longer disclosed to unauthenticated callers.
262+
- `guest.system_company()` hides extra company fields from unauthenticated callers when the `hide_company_public` setting is enabled.
263+
- `guest.system_phone_codes()` no longer accepts a `country` parameter for single-code lookups; it returns all codes.
264+
- `guest.support_ticket_create()` now requires `name`, `email`, `subject`, and `message` parameters through the `RequiredParams` attribute. Rate limiting is enforced.
265+
- Messages submitted via guest ticket creation are now sanitized to prevent XSS.
266+
267+
If your integration depends on any of these guest endpoints, update accordingly.
268+
269+
## Architecture & Module Development Changes
270+
271+
### Symfony HttpKernel Routing
272+
273+
The custom HTTP and routing layer (`Box_App`, `Box_AppAdmin`, `Box_AppClient`) has been replaced by Symfony's HttpKernel, HttpFoundation, and Routing components.
274+
275+
- `Box_App` still exists and exposes `$app->get()`, `$app->post()`, `$app->render()` for backward compatibility in module controllers.
276+
- `Box_App::run()` now returns a `Symfony\Component\HttpFoundation\Response` instead of a string.
277+
- `Box_App::show404()` returns a `Response` object instead of echoing and exiting.
278+
- Module controllers can return `Response` objects directly.
279+
- New `HttpResponseException` allows aborting with a response from anywhere in the call stack.
280+
- `RequestFactory` normalizes route paths from Symfony's `Request` object.
281+
282+
### Box_Mod → FOSSBilling\Module
283+
284+
The `Box_Mod` class has been reworked into `FOSSBilling\Module`:
285+
286+
{% tabs %}
287+
{% tabitem label="Before (0.7.x)" %}
288+
```php
289+
$mod = new Box_Mod('Example');
290+
```
291+
{% /tabitem %}
292+
{% tabitem label="After (0.8.0)" %}
293+
```php
294+
$mod = new FOSSBilling\Module('Example');
295+
```
296+
{% /tabitem %}
297+
{% /tabs %}
298+
299+
The new class uses Symfony Filesystem/Path components internally and supports additional methods like `hasSettingsPage()`, `hasClientController()`, and `hasAdminController()`.
300+
301+
### Paginator Changes
302+
303+
Legacy global paginator usage should be replaced with `FOSSBilling\Paginator` (metadata only) and `FOSSBilling\Pagination` (Doctrine-backed data retrieval):
304+
305+
{% tabs %}
306+
{% tabitem label="Before (0.7.x)" %}
307+
```php
308+
$p = new \Box_Paginator($itemsCount, $currentPage, $limit, $midRange);
309+
```
310+
{% /tabitem %}
311+
{% tabitem label="After (0.8.0)" %}
312+
```php
313+
$p = new \FOSSBilling\Paginator($itemsCount, $currentPage, $limit, $midRange);
314+
$p->toArray(); // Same output format
315+
```
316+
{% /tabitem %}
317+
{% /tabs %}
318+
319+
For Doctrine-backed pagination, use `FOSSBilling\Pagination` with `PaginationOptions`:
320+
321+
```php
322+
$pagination = $this->di['pagination'];
323+
$options = \FOSSBilling\PaginationOptions::fromArray($data);
324+
$result = $pagination->paginateDoctrineQuery($queryBuilder, $options);
325+
```
326+
327+
### Permission System
328+
329+
Permissions have been expanded and enforced more strictly across all modules:
330+
331+
- New `checkPermissionsAndThrowException($module, $permission)` method on the Staff service.
332+
- New `has_permission` Twig function for template-level permission checks.
333+
- Email permission keys added for finer-grained email access control.
334+
- Module names are now normalized in permission checks (`hasManagePermission`).
335+
- Expanded permission checks enforce `'view'` and `'manage_tickets'` etc. throughout modules.
336+
337+
If you have custom admin modules, verify your permission configurations.
338+
339+
### New Twig Infrastructure
340+
341+
The Twig system has been refactored into dedicated classes:
342+
343+
- `FOSSBilling\Twig\TwigFactory` — Creates Twig environments for admin, client, email, adapters, and theme settings.
344+
- `FOSSBilling\Twig\TwigLoader` — New filesystem loader with proper priority: `html_custom/` > `html/` > module templates.
345+
- `FOSSBilling\Twig\Extension\FOSSBillingExtension` — Core filters (`url`, `asset_url`, `trans`, `timeago`, etc.).
346+
- `FOSSBilling\Twig\Extension\ApiExtension` — API-related filters/functions (`api_url`, `fb_api_form`, `fb_api_link`).
347+
- `FOSSBilling\Twig\Extension\LegacyExtension` — Backward-compatible filters (`ip_country_name`, `ip_country_code`, `mod_asset_url`, `period_title`).
348+
- `FOSSBilling\Twig\Extension\DebugBarExtension` — Debug bar integration.
349+
- `FOSSBilling\Twig\EmailPolicy` / `FOSSBilling\Twig\AdapterPolicy` — Sandbox policies for email and adapter templates.
350+
- `FOSSBilling\Twig\SandboxedStringRenderer` — Sandboxed rendering for user-provided template strings.
351+
352+
The old `Box_TwigExtensions` and `Box_TwigLoader` classes have been removed.
353+
354+
## Gravatar Removed
355+
356+
Gravatar has been removed. User avatars are now generated locally using DiceBear. The `gravatar` Twig filter no longer exists; use the `avatar` function instead:
357+
358+
```twig
359+
{{ avatar(email, 80) }}
360+
```
361+
362+
## Honeypot Enabled by Default
363+
364+
The new Antispam module enables honeypot spam prevention by default for supported forms such as signup. If you have custom signup or public submission forms, use the `antispam_honeypot` function to include honeypot fields:
365+
366+
```twig
367+
{\% set honeypot = antispam_honeypot() %}
368+
{\% if honeypot.enabled %}
369+
<input type="text" name="{{ honeypot.field }}" value="" tabindex="-1" autocomplete="off">
370+
{\% endif %}
371+
```
372+
373+
## Rate Limiter
374+
375+
The old `api.rate_*` configuration settings have been replaced by a centralized `rate_limiter` block:
376+
377+
```php
378+
'rate_limiter' => [
379+
'enabled' => true,
380+
'whitelist_ips' => [],
381+
// Override individual policies as needed
382+
],
383+
```
384+
385+
The rate limiter is now enforced on guest ticket creation and other public endpoints. Policies are defined in `FOSSBilling\Security\RateLimiter::getDefaultConfig()`.
386+
387+
## Widget System
388+
389+
0.8.0 introduces a new widget system for rendering dynamic content in template slots. Use `render_widgets` in your theme templates:
390+
391+
```twig
392+
{{ render_widgets('client.theme.body.start') }}
393+
{{ render_widgets('client.theme.body.end') }}
394+
```
395+
396+
Widgets are registered by modules and can be created by implementing the `WidgetProviderInterface`.
397+
398+
## Email Templates
399+
400+
File-backed email templates are now supported in addition to the database-stored templates. The email Twig environment is now sandboxed for security, restricting available filters and globals.
401+
402+
## Deprecations & Removals (Summary)
403+
404+
| Component | Status | Notes |
405+
|-----------|--------|-------|
406+
| `Box_Mod` | Removed | Replaced by `FOSSBilling\Module` |
407+
| `Box_Paginator` | Removed | Replaced by `FOSSBilling\Paginator` |
408+
| `Box_TwigExtensions` | Removed | Split into dedicated extension classes |
409+
| `Box_TwigLoader` | Removed | Replaced by `FOSSBilling\Twig\TwigLoader` |
410+
| `ramsey/uuid` | Removed | Replaced by `symfony/uid` |
411+
| Webpack Encore | Removed | Replaced by esbuild |
412+
| jQuery | Removed | Vanilla JS used throughout |
413+
| Gravatar | Removed | Replaced by DiceBear |
414+
| `Api/API.js` path | Removed | Replaced by `frontend/core/api.js` |
415+
| `DebugBar_renderHead()` | Removed | Use `debug_bar_render_head()` |
416+
| `alink` / `link` filters | Removed | Use `url` with `area` parameter |
417+
| `gravatar` filter | Removed | Use `avatar` function |
418+
| `library_url` filter | Removed | Use `public_asset_url` |
419+
| `markdown` filter | Removed | Use `markdown_to_html` |
420+
| `size` filter | Removed | Use `file_size` |
421+
| `money` / `money_without_currency` filters | Removed | Use `format_currency` |
422+
| `money_convert` / `money_convert_without_currency` filters | Removed | Convert values before rendering, then use `format_currency` |
78423

79424
## Encryption Format Update
80425

0 commit comments

Comments
 (0)