Beta 16 finalizes the PHP extender API, introduces a testing library and JS typings, switches to using namespaces for JS imports, increases extension dependency robustness, and allows overriding routes, among other features.
- A new editor driver abstraction has been introduced, which allows extensions to override the default textarea-based editor with more advanced solutions.
TextEditorButtoncomponents, as well as the
BasicEditorDriverutil (which replaces
SuperTextarea) have been moved from
commonnamespaces should be used when importing. So instead of
import Component from 'flarum/Component', use
import Component from 'flarum/common/Component. Support for the old import styles will be deprecated through the stable release, and removed with Flarum 2.0.
- A typing library has been released to support editor autocomplete for frontend development, and can be installed in your dev environment via
npm install --save-dev [email protected].
- Extension categories have been simplified down to
- All extenders that support callbacks/closures now support global functions like
'boolval'and array-type functions like
serializeToFrontendmethod now supports a default value as the 4th argument.
Eventextender now supports registering subscribers for multiple events at once via a
Notificationextender now has a
beforeSendingmethod, which allows you to adjust the list of recipients before a notification is sent.
ApiSerializerhas been deprecated, and renamed to
removemethods on the
Frontendextenders can be used to remove (and then replace) routes.
ModelPrivateextender replaces the
GetModelIsPrivateevent, which has been deprecated.
- Methods on the
Authextender replace the
CheckingPasswordevent, which has been deprecated.
- All search-related events are now deprecated in favor of the
Filterextenders; this is explained in more detail below.
Laravel and Symfony
Beta 16 upgrades from v6.x to v8.x of Laravel components and v4 to v5 of Symfony components. Please see the respective upgrade guides of each for changes you might need to make to your extensions. The most applicable change is the deprecation of
Symfony\Component\Translation\TranslatorInterface in favor of
Symfony\Contracts\Translation\TranslatorInterface. The former will be removed in beta 17.
event global helper functions have been deprecated.
app has been replaced with
resolve, which takes the name of a container binding and resolves it through the container.
Since some Flarum extensions use Laravel libraries that assume some global helpers exist, we've recreated some commonly used helpers in the flarum/laravel-helpers package. These helpers should NOT be used directly in Flarum extension code; they are available so that Laravel-based libraries that expect them to exist don't malfunction.
As part of our ongoing efforts to make Flarum's search system more flexible, we've made several refactors in beta 16. Most notably, filtering and searching are now treated as different mechanisms, and have separate pipelines and extenders. Essentially, if a query has a
filter[q] query param, it will be treated as a search, and all other filter params will be ignored. Otherwise, it will be handled by the filtering system. This will eventually allow searches to be handled by alternative drivers (provided by extensions), such as ElasticSearch, without impacting filtering (e.g. loading recent discussions). Classes common to both systems have been moved to a
Core's filtering and default search (named SimpleFlarumSearch) implementations are quite similar, as both are powered by the database.
List API controllers call the
filter methods on a resource-specific subclass of
Flarum\Filter\AbstractFilterer. Arguments are an instance of
Flarum\Query\QueryCriteria, as well as sort, offset, and limit information. Both systems return an instance of
Flarum\Query\QueryResults, which is effectively a wrapper around a collection of Eloquent models.
The default systems are also somewhat similar in their implementation.
Filterers apply Filters (implementing
Flarum\Filter\FilterInterface) based on query params in the form
filter[FILTER_KEY] = FILTER_VALUE (or
filter[-FILTER_KEY] = FILTER_VALUE for negated filters). SimpleFlarumSearch's
Searchers split the
filter[q] param by spaces into "terms", apply Gambits (implementing
Flarum\Search\GambitInterface) that match the terms, and then apply a "Fulltext Gambit" to search based on any "terms" that don't match an auxiliary gambit. Both systems then apply sorting, an offset, and a result count limit, and allow extensions to modify the query result via
Extensions add gambits and search mutators and set fulltext gambits for
Searcher classes via the
SimpleFlarumSearch extender. They can add filters and filter mutators to
Filterer classes via the
With regards to upgrading, please note the following:
- Search mutations registered by listening to the
Searchingevents for discussions and users will be applied as to searches during the search mutation step via a temporary BC layer. They WILL NOT be applied to filters. This is a breaking change. These events have been deprecated.
- Search gambits registered by listening to the
ConfigureDiscussionGambitsevents will be applied to searcher via a temporary BC layer. They WILL NOT be applied to filters. This is a breaking change. These events have been deprecated.
- Post filters registered by listening to the
ConfigurePostsQueryevents will be applied to post filters via a temporary BC layer. That event has been deprecated.
flarum/testing package provides utils for PHPUnit-powered automated backend tests. See the testing documentation for more info.
Beta 15 introduced "extension dependencies", which require any extensions listed in your extension's
require section to be enabled before your extension can be enabled.
With beta 16, you can specify "optional dependencies" by listing their composer package names as an array in your extension's
extra.flarum-extension.optional-dependencies. Any enabled optional dependencies will be booted before your extension, but aren't required for your extension to be enabled.
Access Token and Authentication Changes
Extension API changes
The signature to various method related to authentication have been changed to take
$token as parameter instead of
$userId. Other changes are the result of the move from
Flarum\Http\AccessToken::generate($userId)no longer accepts
$lifetimeas a second parameter. Parameter has been kept for backward compatibility but has no effect. It will be removed in beta 17.
Flarum\Http\RememberAccessToken::generate($userId)should be used to create remember access tokens.
Flarum\Http\DeveloperAccessToken::generate($userId)should be used to create developer access tokens (don't expire).
Flarum\Http\SessionAccessToken::generate()can be used as an alias to
Flarum\Http\AccessToken::generate(). We might deprecate
AccessToken::generate()in the future.
Flarum\Http\Rememberer::remember(ResponseInterface $response, AccessToken $token): passing an
AccessTokenhas been deprecated. Pass an instance of
RememberAccessTokeninstead. As a temporary compatibility layer, passing any other type of token will convert it into a remember token. In beta 17 the method signature will change to accept only
Flarum\Http\Rememberer::rememberUser()has been deprecated. Instead you should create/retrieve a token manually with
RememberAccessToken::generate()and pass it to
Flarum\Http\SessionAuthenticator::logIn(Session $session, $userId)second parameter has been deprecated and is replaced with
$token. Backward compatibility is kept. In beta 17, the second parameter method signature will change to
AccessToken::generate()now saves the model to the database before returning it.
::findOrFail($id)can no longer be used to find a token, because the primary key was changed from
id. Instead you can use
- It's recommended to use
AccessToken::whereValid(): Illuminate\Database\Eloquent\Builderto find a token. This will automatically scope the request to only return valid tokens. On forums with low activity this increases the security since the automatic deletion of outdated tokens only happens every 50 requests on average.
Symfony session changes
If you are directly accessing or manipulating the Symfony session object, the following changes have been made:
user_idattribute is no longer used.
access_tokenhas been added as a replacement. It's a string that maps to the
tokencolumn of the
To retrieve the current user from inside a Flarum extension, the ideal solution which was already present in Flarum is to use
$request->getAttribute('actor') which returns a
User instance (which might be
To retrieve the token instance from Flarum, you can use
To retrieve the user data from a non-Flarum application, you'll need to make an additional database request to retrieve the token. The user ID is present as
user_id on the
Token creation changes
lifetime property of access tokens has been removed. Tokens are now either
session tokens with 1h lifetime after last activity, or
session_remember tokens with 5 years lifetime after last activity.
remember parameter that was previously available on the
POST /login endpoint has been made available on
POST /api/token. It doesn't return the remember cookie itself, but the token returned can be used as a remember cookie.
lifetime parameter of
POST /api/token has been deprecated and will be removed in Flarum beta 17. Partial backward compatibility has been provided where a
lifetime value longer than 3600 seconds is interpreted like
remember=1. Values lower than 3600 seconds result in a normal non-remember token.
developer tokens that don't expire have been introduced, however they cannot be currently created through the REST API. Developers can create developer tokens from an extension using
If you manually created tokens in the database from outside Flarum, the
type column is now required and must contain
developer. Tokens of unrecognized type cannot be used to authenticate, but won't be deleted by the garbage collector either. In a future version extensions will be able to register custom access token types.
Token usage changes
A security issue in Flarum previously caused all tokens to never expire. This had limited security impact due to tokens being long unique characters. However custom integrations that saved a token in an external database for later use might find the tokens no longer working if they were not used recently.
If you use short-lived access tokens for any purpose, take note of the expiration time of 1h. The expiration is based on the time of last usage, so it will remain valid as long as it continues to be used.
Due to the large amount of expired tokens accumulated in the database and the fact most tokens weren't ever used more than once during the login process, we have made the choice to delete all access tokens a lifetime of 3600 seconds as part of the migration, All remaining tokens have been converted to
The remember cookie still works like before, but a few changes have been made that could break unusual implementations.
Now only access tokens created with
remember option can be used as remember cookie. Any other type of token will be ignored. This means if you create a token with
POST /api/token and then place it in the cookie manually, make sure you set
remember=1 when creating the token.
Web session expiration
In previous versions of Flarum, a session could be kept alive forever until the Symfony session files were deleted from disk.
Now sessions are linked to access tokens. A token being deleted or expiring will automatically end the linked web session.
A token linked to a web session will now be automatically deleted from the database when the user clicks logout. This prevents any stolen token from being re-used, but it could break custom integration that previously used a single access token in both a web session and something else.
- The IP address is now available in requests via
- Policies can now return
falseas aliases for
user.editpermission has been split into
user.editCredentials(for email, username, and password), and
user.edit(for other attributes).
- There are now permissions (
bypassTagCounts) that allow users to bypass tag count requirements.
- Flarum now supports PHP 7.3 - PHP 8.0, with support for PHP 7.2 officially dropped.