Skip to content

Commit ebc3980

Browse files
committed
Release 2.3.0
1 parent 64a91cf commit ebc3980

84 files changed

Lines changed: 343 additions & 19 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,98 @@
11
# Changelog
22

3+
# [2.3.0](https://github.com/getformwork/formwork/releases/tag/2.3.0)
4+
5+
**Enhancements**
6+
- **Add Events functionality**
7+
- **Add Plugins functionality**
8+
- **Add support for AVIF images**
9+
- **Expose error messages in the panel for invalid fields after submission**
10+
- **Add Hungarian and Swedish translations** (🤖 AI generated, reviews are welcome)
11+
- **Improve dark color scheme styles in the panel**
12+
- **Add new `Authenticator` service to decouple authentication from panel**
13+
- **Implement PSR-3 compatible `Logger`**
14+
- **Implement PSR-11 `ContainerInterface`**
15+
- **Implement PSR-14 `EventDispatcherInterface`**
16+
- Store validated data with `Model::set()` if there is a corresponding field
17+
- Correctly set `ReadonlyModelProperty` attribute to avoid unexpected changes to model properties
18+
- Move fields initialization and validation to `Page::load()`
19+
- Add the possibility to create pages from the constructor by retrieving `App` instance if not provided
20+
- Sync page data with fields in `Page::load()`
21+
- Add `Config::hasMultiple()`
22+
- Add `Config::getMultiple()`
23+
- Add `Config::set()` and `Config::setMultiple()`
24+
- Add `Schemes::getMultiple()` and `Schemes::getAll()`
25+
- Add `Translations::getMultiple()` and `Translations::getAll()`
26+
- Allow Scheme extension with `Scheme::extend()` and `Scheme::extendWith()`
27+
- Set validated status even if validation fails
28+
- Add context to `InvalidValueException`
29+
- Add the possibility to get translated validation error
30+
- Add styles for invalid fields
31+
- Add the possibility to pass route actions parameters
32+
- Add view namespaces
33+
- Make Assets a service resolving namespaced resources
34+
- Add the possibility to set `NavigationItem` visibility in the panel
35+
- Add the possibility to specify config prefix with `Config::loadFile()` and `Config::loadFromPath()`
36+
- Add `Arr::extend()`, `Arr::override()` and `Arr::exclude()` to handle data with more consistency
37+
- Add default values support to field config files
38+
- Add `Form` class to streamline incoming data process and validation
39+
- Add Plugins views to panel
40+
- Add specific exception classes for `Image`
41+
- Add `User::save()`, `User::delete()` and `User::deleteImage()`
42+
- Add custom session handler
43+
- Add the possibility to specify the number of retry attempts (by default 10) of the `serve` command to bind to an available port
44+
- Improve panel navigation spacing
45+
- Improve panel header styles
46+
- Use consistent border-radius and box-shadow values in panel styles
47+
- Improve array input spacing and sortable styles in panel
48+
- Use click event instead of mousedown to avoid unexpected actions in the panel
49+
- Allow `Container::buildArguments()` to use default values for unspecified classes, interfaces and support variadic parameters
50+
- Add the possibility to set auto color scheme to the panel login
51+
- Avoid processing HTTP ranges for responses requiring empty content
52+
53+
**Bug fixes**
54+
- Allow and return an appropriate value for empty non-required fields
55+
- Correctly merge dotted keys with `Config::loadFile()`
56+
- Ignore empty values passed to `Html::classes()`
57+
- Iterate all fields to ensure all validations are run in `FieldCollection::isValid()`
58+
- Validate unique slug with unspecified root
59+
- Fix HTTP Range handling for file responses (RFC 7233–compliance and Safari compatibility)
60+
- Define default section for layoutless schemes
61+
- Clear image transforms after processing images in `Image::saveAs()`
62+
- Fix `serve` command failing with log messages containing brackets
63+
- Fix config service loading with missing cache/config folder
64+
- Fix translations service loading with missing site/translations folder
65+
- Normalize and ensure `Panel::route()` is inside the panel root
66+
- Fix no tab selection from invalid local storage value in the panel interface
67+
- Fix backtrace frame dumping for unreflectable functions
68+
- Handle potential exceptions when initializing contentFile in Page class
69+
- Correctly add tooltips to panel editor toolbar commands
70+
- Check if site/files is a directory before getting files
71+
- Fix metadata prefix set even if a colon is not present in the name
72+
- Fix `DomSanitizer::sanitizeUri()` throwing exception for valid empty values
73+
- Remove leading and trailing whitespace with `Text::normalizeWhitespace()`
74+
- Return empty array if input is empty with `Text::splitWords()`
75+
- Fix discarded stdout/stderr data while serving pages with the `serve` command
76+
- Always close connections and restore error handlers in the `Client` class
77+
- Always close streams in `FileResponse::send()`
78+
- Avoid errors for undefined data keys in `Str::interpolate()`
79+
- Set correct 403 Forbidden status when CSRF token is invalid on XHR requests
80+
- Ensure `MimeType::fromFile()` is given a readable file
81+
- Check if file was actually uploaded in `FileUploader::upload()`
82+
83+
**Security**
84+
- Normalize assets paths to avoid directory traversal
85+
- Avoid potentially broken "deflate" responses and throw on unsupported content encodings
86+
87+
**Deprecations**
88+
- Poorly-named `$dateField->toDuration()` deprecated in favor of `$dateField->toTimeDistance()`
89+
- `Log` class deprecated in favor of the new PSR-3 compatible `Logger`
90+
- Page setter methods deprecated in favor of using `$page->set()`
91+
- `Page::isSlugEditable()` and `Page::isSlugReadonly()`
92+
- `Panel::assets()` in favor of the `Assets` service
93+
- `system.panel.loginAttempts` and `system.panel.loginResetTime` options in favor of `system.authentication.limits.maxAttempts` and `system.authentication.limits.resetTime`
94+
- `system.panel.sessionDuration` option in favor of `system.session.duration`
95+
396
# [2.2.2](https://github.com/getformwork/formwork/releases/tag/2.2.2)
497

598
**Enhancements**

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2018-2025 Giuseppe Criscione
3+
Copyright (c) 2018-2026 Giuseppe Criscione and contributors
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

formwork/fields/date.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
* @deprecated since 2.3.0 Use `$field->toTimeDistance()` instead
4949
*/
5050
'toDuration' => function (Field $field): string {
51-
trigger_error('$field->toDuration() is deprecated since Formwork 2.3.0 and will be removed in a future release. Use $field->toTimeDistance() instead', E_USER_DEPRECATED);
51+
trigger_error('$field->toDuration() is deprecated since Formwork 2.3.0. Use $field->toTimeDistance() instead', E_USER_DEPRECATED);
5252
return $field->toTimeDistance();
5353
},
5454

@@ -57,6 +57,8 @@
5757
*
5858
* The string is formatted as a human-readable translated string representing
5959
* the distance between the field value and the current time.
60+
*
61+
* @since 2.3.0
6062
*/
6163
'toTimeDistance' => function (Field $field) use ($app): string {
6264
return $field->isEmpty() ? '' : Date::formatTimestampAsDistance($field->toTimestamp(), $app->translations()->getCurrent());

formwork/src/Assets/Assets.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public function __construct()
3131
* Set assets resolution paths
3232
*
3333
* @param array<string, array{path: string, uri: string}> $paths
34+
*
35+
* @since 2.3.0
3436
*/
3537
public function setResolutionPaths(array $paths): void
3638
{
@@ -105,6 +107,8 @@ public function images(): AssetCollection
105107
* Resolve asset path and URI from key, supporting namespaced syntax
106108
*
107109
* @return array{path: string, uri: string}
110+
*
111+
* @since 2.3.0
108112
*/
109113
protected function resolve(string $key): array
110114
{

formwork/src/Assets/Exceptions/AssetResolutionException.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44

55
use RuntimeException;
66

7+
/**
8+
* @since 2.3.0
9+
*/
710
class AssetResolutionException extends RuntimeException {}

formwork/src/Authentication/Authenticator.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
use Formwork\Users\Users;
1111
use SensitiveParameter;
1212

13+
/**
14+
* @since 2.3.0
15+
*/
1316
class Authenticator
1417
{
1518
public const string SESSION_LOGGED_USER_KEY = '_formwork_logged_user';

formwork/src/Authentication/Exceptions/AuthenticationFailedException.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44

55
use RuntimeException;
66

7+
/**
8+
* @since 2.3.0
9+
*/
710
class AuthenticationFailedException extends RuntimeException {}

formwork/src/Authentication/Exceptions/RateLimitExceededException.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
use RuntimeException;
66
use Throwable;
77

8+
/**
9+
* @since 2.3.0
10+
*/
811
class RateLimitExceededException extends RuntimeException
912
{
1013
/**

formwork/src/Authentication/Exceptions/UserNotLoggedException.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44

55
use RuntimeException;
66

7+
/**
8+
* @since 2.3.0
9+
*/
710
class UserNotLoggedException extends RuntimeException {}

formwork/src/Authentication/RateLimiter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
use Formwork\Http\Request;
77
use Formwork\Log\Registry;
88

9+
/**
10+
* @since 2.3.0
11+
*/
912
final class RateLimiter
1013
{
1114
/**

0 commit comments

Comments
 (0)