Updating from 3.1 to 3.2
This page lists what is specific to the move from Thelia 3.1 to 3.2, patch releases 3.2.1, 3.2.2 and 3.2.3 included. The procedure itself (backup, Composer, database script, cache, assets, modules) is on Update; the steps below come on top of it. If you start from 3.0, apply Updating from 3.0 to 3.1 first.
Before you update
- Back up the files and the database, as described in Update.
- If your
composer.jsonrequires API Platform with^4.4, change it to^4.3. The 3.2 core pins API Platform to 4.3.x and declares a deliberate conflict with 4.4, so the update can move API Platform down from 4.4. - If you start from 3.1.0 and have not run it since, empty the image cache after the update
with
php bin/console image-cache:clear. It is part of the 3.1.1 release, see Updating from 3.0 to 3.1. - List the modules your shop runs that read image files (see Image files per language) and the modules that handle payments (see Payment modules).
What the update script does now
php local/setup/update.php changed in 3.2:
- It accepts
-nor--no-interaction. - It exits with code 0 when the database is already up to date.
- It purges
var/cache/<env>andvar/propel/<env>itself before it starts.
php local/setup/update.php --no-interaction
The script also performs these changes on the database:
- It copies the image file into the translation of each active language, then drops the
filecolumn of the image tables (see Image files per language). - It switches
active-admin-templatetodefault-twigand deactivates TheliaSmarty (see The Smarty back-office is gone).
After the Composer update
Run the module refresh once Composer is done:
php Thelia module:refresh
A module newly shipped with the release is registered inactive. Activate it from the
back-office, or with php Thelia module:activate <ModuleCode>.
TheliaCMS (thelia/cms-module) is not required by the skeleton. To add it to a project:
composer require thelia/cms-module
php Thelia module:refresh
Changes that need your attention
API Platform stays on 4.3
The core pins API Platform to 4.3.x and conflicts with 4.4 on purpose. A project that requires
^4.4 cannot resolve: set the constraint back to ^4.3 in composer.json.
Add one setting to config/packages/api_platform.yaml. It removes the "multiple ApiResource
with the same shortName" warnings:
# config/packages/api_platform.yaml
api_platform:
defaults:
extra_properties:
deduplicate_resource_short_names: true
Image files per language
The file column of product_image, category_image, content_image, folder_image,
brand_image and module_image is removed. Each image now carries its file in its translation,
so an image can differ from one language to the next. The update script copies the existing file
into the translation of every active language. How a merchant uses it is described in
Product media.
A module that read the file column has to read file from the matching *_image_i18n table
instead (product_image_i18n, category_image_i18n, and so on). Check the modules that
export or display images; for example, GoogleShoppingXml and EasyProductManager need their
4.0.0 versions.
The Smarty back-office is gone
The Smarty back-office is removed. The update script sets active-admin-template to
default-twig and deactivates TheliaSmarty. A shop that still wants the Smarty back-office
adds thelia/backoffice-default-template itself; that package is no longer maintained.
Back-office CSRF token
The back-office still accepts the CSRF token in the URL, but this is deprecated and 3.3 will refuse it. A module that builds back-office requests sends the token in the POST body instead. Toggles, position changes and deletions require the token: a request without a valid one answers 403.
Themes
Flexy and default-twig 1.2 are required: the 3.2 core refuses a theme older than 1.2, and the
3.2.1 core a default-twig older than 1.2.2 (see Patch release 3.2.1).
Updating through thelia/thelia-skeleton brings them. If you forked Flexy 1.1:
- Take over the
GuestOrderPlacedSubscriberfix of Flexy 1.2: the core no longer raisesORDER_CART_CLEAR. - Your theme can now read the content slots.
Payment modules
The payment flow changed: supportsPaymentRetry() is a new part of the contract, the cart is
kept until the payment completes, and the amount is checked together with the shipping cost.
Review each payment module of the shop against
Payment modules.
Converting a database migrated from Thelia 2 to utf8mb4
Thelia 2 created its tables in utf8 (utf8mb3) and the migration keeps them in it. Thelia 3
connects in utf8mb4, and a fresh install creates its tables in utf8mb4. On a migrated shop
the database refuses an emoji, or any other character outside the Basic Multilingual Plane,
with error 1366 ("Incorrect string value"), while a fresh install stores it.
The update script does not convert these tables. The conversion rebuilds each table and locks it for writes while it runs, for a time that grows with its size, so you run it yourself, once, during a maintenance window. The command arrives with 3.2. List what would change first:
php bin/console thelia:database:convert-utf8mb4
The command lists each table that is not in utf8mb4 with its columns and approximate size.
It flags the tables it moves from the COMPACT to the DYNAMIC row format: in COMPACT,
InnoDB caps an index at 767 bytes, a VARCHAR(255) in utf8mb4 needs 1020, and the fresh
install creates its tables in DYNAMIC. It also names what it cannot convert on its own and
converts nothing until that is settled: a text column used by a foreign key, or an index longer
than the engine accepts. A table in another character set, such as latin1, is reported and
left alone, because its bytes may be UTF-8 written through a latin1 connection.
Back the database up, then convert:
php bin/console thelia:database:convert-utf8mb4 --force
Each table moves to utf8mb4 with utf8mb4_general_ci, the collation of the fresh install,
and its TEXT columns stay TEXT. The database default follows, so a module installed later
creates its tables in utf8mb4. If a table fails, the command stops there and prints the
database error. The tables converted before it stay converted, and the next run picks up the
rest. --table=<name>, repeated, converts only the named tables, which lets you spread the
largest ones over several windows.
Rebuild the assets
Recompile the assets of the themes after the update:
php Thelia importmap:install
php Thelia tailwind:build
php Thelia sass:build
Patch release 3.2.1
3.2.1 is a security and maintenance release of the 3.2 line, without any breaking change. It
ships setup/update/sql/3.2.1.sql, which renames the tax types a shop migrated from Thelia 2
still stores under their Thelia 2 class, declares the back-office hooks the Twig templates call,
and records the new version. thelia/setup ships as 3.2.1 with this core; thelia/config does
not change and stays at 3.2.0. The full notes are on the
GitHub release.
composer update thelia/thelia-skeleton --with-all-dependencies
php local/setup/update.php
php Thelia cache:warmup --env=prod
The core refuses a back-office theme thelia/backoffice-default-twig-template older than 1.2.2.
Update it to 1.2.2, and the front theme thelia/flexy to 1.2.1, at the same time: updating
through thelia/thelia-skeleton brings both.
When the web server user owns the cache of the previous release, the update script moves it
aside instead of dying, and stops with code 8 only when it cannot even move it. See
Update.
Security fixes
- GHSA-5524-qfxp-33v9:
the upload policy now checks the name a file is stored under as well as the name it was sent
with, and storage refuses a server-executable name.
MediaFacade::uploadImage()andMediaFacade::uploadDocument()apply the upload policy. - GHSA-7wrm-pcw6-4g9m:
documents with an HTML, XHTML, XML, XSL, JavaScript or compressed SVG extension are refused,
whatever
document_upload_forbidden_extensionssays; the list isFileConfiguration::BROWSER_ACTIVE_DOCUMENT_EXTENSIONS. The file endpoints of the API serve a document as a download, and the web server has to do the same for the document cache (see Web server). - GHSA-gcgv-f8rf-w2wc:
a text cell of a CSV export, from the core or from a module, that starts with
=,+,-,@, a tab or a carriage return now gets a leading'and stays text. A plain number such as-5.00or+33612345678is written unchanged, and a cell holding,or;is enclosed in quotes. JSON, XML and YAML exports are unchanged. The back-office theme 1.2.2 writes the newsletter subscriber export the same way.
Web server
Thelia publishes the documents under public/cache/documents/, and the web server serves them
without going through PHP:
- on nginx, add the
location ^~ /cache/documents/block given in Nginx configuration to the server block of the shop; - on Apache, the update script writes
public/cache/documents/.htaccess. It needs theFileInfooverride thatpublic/.htaccessalready needs, andmod_headers. See Apache configuration.
Files uploaded before the update
The update refuses such uploads from now on, but it leaves the files already stored where they are. Look for an image or a document stored under a name a web server runs (GHSA-5524-qfxp-33v9), and for a document a browser opens as a page or runs as a script (GHSA-7wrm-pcw6-4g9m). From the root of the project, with GNU find:
find local/media public/cache -regextype posix-extended \
! -type d ! -path public/cache/documents/.htaccess \
\( -iregex '.*/[^/]*\.(ph(p[3-8st]?|t(ml?)?|ar)|s(html?|tm)|ht(access|passwd))(\.[^/]*)?' \
-o -iregex '[^/]+/[^/]+/documents/.*\.(html?|x(ht(ml?)?|ml|slt?|spf|ul)|m(ht(ml)?|ml)|r(df|ss)|atom|kml|svgz|[cm]?js)' \) \
-print
The first pattern finds a server-executable extension anywhere in a file name (report-1.php,
shell.php.jpg), among images and documents; the second finds an HTML, XML, XSL, JavaScript or
compressed SVG document. The command only lists files. It skips the .htaccess the update
writes, and it lists the links of the cache whose target is already gone. If the shop keeps its
media or its document cache elsewhere (document_cache_dir_from_web_root), change the paths.
For each file listed under local/media/, delete the image or the document from the back
office, on the Images or Documents tab of its product, category, content, folder or brand, so
its row goes too. Then run the command again with -delete in place of -print to remove the
files left behind.
Deleting an image or a document over the admin API removes its row and leaves its files, and
deleting it from the back office leaves its copy under public/cache/. A file deleted that way
is still served at its URL: the command lists it as well, and -delete removes it.
Other fixes
- A shop migrated from Thelia 2 with a fixed amount tax or a feature amount tax (eco-tax)
prices the products under these taxes again:
3.2.1.sqlmoves them to their Thelia 3 class. Computing a price failed with "Recorded type ... does not exists". - The back-office hooks the Twig templates call,
customer.tab,customer.tab-contentandcustomer-edit.actionsamong them, are declared. A module subscribing to one of them was dropped when the container was built ("Hook customer.tab is unknown."), and its section never showed. A hook a module already created keeps its id and its titles. - The pickup location provider reads its search parameters (radius, address, country, module
ids) from the filters of the operation context, so
resources()in a front theme can pass them. - The
/fileendpoints of the front and admin API answer a browser opening the URL; they answered 500 when theAcceptheader puttext/htmlfirst. - The customer export writes the first and last names under their own column labels; they were swapped.
Patch release 3.2.2
3.2.2 is a maintenance release of the 3.2 line. It fixes coupons and automatic promotions, the
refund of a return that carries the postage, and a reserved operation that showed to every
visitor while it was not running. It ships setup/update/sql/3.2.2.sql, which changes no schema
and records the new version. thelia/setup ships as 3.2.2 with this core; thelia/config stays
at 3.2.0 and the themes do not change. The full notes are on the
GitHub release.
composer update thelia/thelia-skeleton --with-all-dependencies
php local/setup/update.php
php Thelia cache:warmup --env=prod
A coupon that removes an amount or a percentage on products, categories or attribute values, and a free product coupon, kept only the first entry of its list when it was saved from the back-office, and discounted nothing. After the update it applies to that first entry only: open each of these coupons, select the whole list again and save it. The coupon conditions need nothing: the values already saved are read correctly from now on.
For module developers: getFreeShippingForCountries() and getFreeShippingForModules() of a
coupon return CouponCountry and CouponModule rows instead of arrays of plain values. In
FacadeInterface, getDeliveryAddress() may return null and
getNbArticlesInCartIncludeQuantity() a float; an implementation that declares the former
return types stays compatible.
Patch release 3.2.3
3.2.3 is a security and maintenance release of the 3.2 line. It fixes
GHSA-q679-2j8v-rh79:
a signed-in customer updating their account through the front API could write the fields a
module adds to the customer and reserves to the administration, such as the customer family of
CustomerFamily, and the same request emptied their e-mail, so they could no longer sign in.
Deleting an image or a document, in the back office or over the API, now also removes what the
shop published to serve it (see
Deleting an image or a document).
It ships setup/update/sql/3.2.3.sql, which changes no schema and records the new version.
thelia/setup ships as 3.2.3 with this core; thelia/config stays at 3.2.0 and the themes do
not change. The full notes are on the
GitHub release.
composer update thelia/thelia-skeleton --with-all-dependencies
php local/setup/update.php
php Thelia cache:warmup --env=prod
For module developers: a field a module adds to an API resource is written only when it carries
a #[Groups] attribute naming a write group of the operation, as the fields of the resource
itself do. A field without such a group is no longer written by an operation that declares
groups.
Checklist
composer update thelia/thelia-skeleton --with-all-dependenciesphp local/setup/update.php --no-interactionphp Thelia cache:warmup --env=prodphp Thelia importmap:install && php Thelia tailwind:build && php Thelia sass:buildphp Thelia module:refresh, then activate the new modules you want.config/packages/api_platform.yaml: adddeduplicate_resource_short_names.- Check the image-reading modules and the payment modules.
- If your database comes from Thelia 2: list the tables with
php bin/console thelia:database:convert-utf8mb4, then convert them during a maintenance window (see Converting a database migrated from Thelia 2 to utf8mb4). - nginx: add the document cache block to the server block (see Web server).
- List the files uploaded before the update and remove the ones the command finds (see Files uploaded before the update).
- Open the list coupons and the free product coupons saved from the back-office, select the whole list again and save them (see Patch release 3.2.2).