Developer’s guide to upgrading from webtrees 2.2 to 2.3
This document describes the breaking changes and notable API differences between webtrees 2.2.x and 2.3.x that affect authors of third-party modules.
Time and Timestamps
Our Timestamp class is replaced by CarbonImmutable.
Our TimeFactory class is replaced by PSR-20 ClockInterface.
// Create a timestamp
$timestamp = Registry::timestampFactory()->fromEpoch(time());
$timestamp = Registry::timestampFactory()->now();
$timestamp = Registry::timestampFactory()->fromString($date_string);
// Use CarbonImmutable methods directly
$timestamp->diffForHumans();
$timestamp->format('Y-m-d');
$timestamp->addDays(7);
// Julian day is now available from the timestamp factory, rather than a timestamp
$julian_day = Registry::timestampFactory()->todayJulianDay();
HTTP requests
Guzzle is replaced by PSR-18 ClientInterface, with the symfony/http-client implementation.
$http_client = Registry::container()->get(ClientInterface::class);
$request_factory = Registry::container()->get(RequestFactoryInterface::class);
$request = $request_factory->createRequest('GET', 'https://example.com/api');
try {
$response = $http_client->sendRequest($request);
} catch (ClientExceptionInterface) {
// Handle connection failure
}
Languages and localisation
Our language modules have been replaced with language classes, in /app/I18N.
Logic from the package fisharebest/localization has been imported.
Previously, we used translation to generate dates and relationship names. These are now generated by the language classes, using custom logic for each language.
The main updates to I18N are;
I18N::language(): LanguageInterfacethe current language - replaces->locale()I18N::languageTag()e.g.en-USI18N::formatDate($date)I18N::formatList($array)-['red','green','blue'] => 'red, green, blue'I18N::formatListAnd($array)-['red','green','blue'] => 'red, green and blue'I18N::formatListOr($array)-['red','green','blue'] => 'red, green or blue'
The translator/translation functions are rewritten. To create an array of translations from a .PO or .MO file, use the following.
$stream = fopen($po_file, 'rb');
$translations = Translation::fromPoStream($stream)->toArray();
fclose($stream);
Generating thumbnail images
We no longer use intervention/image. Instead, we call GD functions directly.
ImageMagick is no longer needed or supported, as GD is faster and requires less memory.
ImageFactoryInterface has been simplified. Generating watermarks is (will soon be) a
separate concern.
HTML editors
We replaced CKEditor4 with TinyMCE. TinyMCE is simpler and more lightweight.
For server-side filtering, ezyang/htmlpurifier was abandoned, and is
replaced by symfony/html-sanitizer.
PSR-11 Container
Our container now supports lazy instantiation.
$container->bind($class_or_interface_name, $concrete_class_name);
New Enums
We now make extensive use of Enums. See /app/Enums/...
The major ones are:
Restriction - replaces the strings 'PRIVACY', 'CONFIDENTIAL', 'LOCKED', etc.
UserRole - replaces the constant strings 'none', 'access', 'edit', 'accept', 'admin'
AccessLevel - replaces the constant integers -1, 0, 1, 2
To check whether a user has permission to do something, change
$user_access_level = Auth::accessLevel($user);
$required_access_level = (int) $tree->getPreference('CAN_DO_SOMETHING');
if ($required_access_level >= $user_access_level) {...}
to
$user_access_level = Auth::accessLevel($user);
$required_access_level = AccessLevel::fromTreePreference($tree, 'CAN_DO_SOMETHING');
if ($required_access_level->allows($user_access_level) {}
Sorting records
To sort records by one of its properties or methods, we have new helpers
usort($family_array, FamilyComparator::byMarriageDate());usort($individual_array, IndividualComparator::byBirthDate());etc.
CLI tools and build scripts
Composer scripts have been updated. Run composer list to see them.
webtrees CLI scripts have been updated. Run php index.php list to see them.