Moving a site from LoveStack
Most sites do not need to do anything. If you run Exponential and never ran LoveStack, nothing on this page applies to you. The features Exponential took over from LoveStack are part of 6.0.15, switched off where they could change how an existing site behaves.
This page is for those who run LoveStack (Mugo Web's distribution of the legacy kernel,
mugoweb/ezpublish-legacy) and want to move a site to Exponential 6, and for developers who used
a LoveStack-only API in their own code. A LoveStack database is close to Exponential's, so the
move is mostly an ordinary upgrade with two extra commands. The upgrade guide has the same path
in short: Coming from LoveStack.
Step 1 — Do you need to do anything?
Run this from your installation root:
grep -l -i "lovestack" lib/version.php composer.json composer.lock 2>/dev/null| What it prints | What it means | What to do |
|---|---|---|
| Nothing | this installation is not LoveStack | nothing; you are done |
lib/version.php (and maybe composer.*) | this installation runs LoveStack | read on |
To check a database rather than the code (for example a copy you were given):
SELECT name, value FROM ezsite_data
WHERE name IN ( 'ezpublish-version', 'db-schema-version' );lovestack and a db-schema-version row mean a LoveStack database; a number such as
6.0.15stable means Exponential. Once Exponential is installed (step 3), one command does both
checks and also lists the settings and extensions that need attention:
./console exp:lovestack checkStep 2 — Before you start
Back up the code, the database and the storage directory:
tar czf ../site-code-backup.tar.gz --exclude=var/cache --exclude='var/*/cache' . mysqldump --single-transaction --routines mydatabase > ../site-db-backup.sql tar czf ../site-storage-backup.tar.gz var/storage var/*/storageReplace
mydatabase(usepg_dumpfor PostgreSQL). Keep the backups until the moved site has run for a while.Check PHP. Exponential 6 runs on PHP 8.0 to 8.5 (PHP 7.4 usable without support). LoveStack's
composer.jsonallows PHP 7.3–7.4 and 8.1–8.3, so a site on PHP 7 moves to PHP 8 at the same time:php -v.List your own code. Everything you or your agency wrote lives in your own extensions,
settings/override/andsettings/siteaccess/. Those are what you carry over; the kernel,extension/ezjscore,extension/ezoeandextension/ezformtokencome with Exponential.ls extension/ settings/override/ settings/siteaccess/
Step 3 — Install Exponential next to the old site
Install Exponential in a new directory, as the installation guide describes, for example:
cd /var/www
composer create-project se7enxweb/exponential exponentialDo not unpack Exponential over the LoveStack directory: files that LoveStack moved (for example
the ezenum datatype, which LoveStack keeps in extension/legacy_2018) would be left in two
places. Then copy your own parts across:
OLD=/var/www/lovestack-site
NEW=/var/www/exponential
cp -a $OLD/extension/myextension $NEW/extension/ # once per own extension
cp -a $OLD/settings/override/. $NEW/settings/override/
cp -a $OLD/settings/siteaccess/. $NEW/settings/siteaccess/
cp -a $OLD/var/storage $NEW/var/ # or var/<site>/storageNow run the check in the new directory, against the copied settings and the old database:
./console exp:lovestack checkEach line is marked FOUND (something to do; the line below says what), info (present, and
Exponential works with it as it is), clear (not present) or unknown (the engine does not
tell). It ends with OK (exit code 0) or NEEDS ATTENTION (exit code 1); --json gives a
machine-readable report. It writes nothing.
Step 4 — Settings
4.1 Remove legacy_2018
LoveStack moved the ezenum datatype into an extension called legacy_2018. Exponential keeps
ezenum in the kernel, so the extension must not be active (two classes called eZEnumType
would collide):
grep -rn "legacy_2018" settings/override settings/siteaccessRemove every ActiveExtensions[]=legacy_2018 and ActiveAccessExtensions[]=legacy_2018 line
it prints. Content using ezenum keeps working. Do not copy the extension directory.
4.2 Rename or remove LoveStack-only settings
exp:lovestack check lists them, with the Exponential name to use. In short:
| LoveStack setting | In Exponential |
|---|---|
site.ini [Session] SameSite= | site.ini [Session] CookieSameSite= (default Lax; None needs Secure). Until you rename it, Exponential reads SameSite and logs a deprecation note |
site.ini [HTTPHeaderSettings] SetContentLengthHeader= | remove: Velocity, FrankenPHP and the HTTP cache send Content-Length themselves |
site.ini [DebugSettings] UsedTemplateEditUrl= | same name and meaning (L10) |
site.ini [Cache_ezjscore] Maxage= | remove: packed files are cleared by ./console exp:cache |
image.ini [ValidUploadFormats] MIMEList[] | image.ini [ImageUploadSettings] AllowedMIMETypes[] (L05) |
error.ini [HTTPError-<code>] HeaderList[] | same name and meaning (L29) |
ezfind.ini [SearchSettings] SortBy[] (ezjscore search) | same name and meaning (L30) |
ezjscore.ini [eZJSCore] LocalScriptBasePath, [YUI3] LoaderOptions | remove: Exponential's ezjscore ships no YUI |
ezjscore.ini [ezjscServer_ezjscnode] Functions[] | same; to require the policy, also set RequirePolicy=enabled (L01) |
menu.ini [Leftmenu_my] PolicyList_edit_profile | remove: not read by Exponential's admin menu |
content.ini [CustomTagSettings] IsHidden[] | same name and meaning (L22) |
[Include path/*.ini] inside an INI file | same syntax (L28) |
ezoe.ini [EditorSettings] Plugins[]=custom_tags_controls, design.ini EditorCSSFileList[]=mugo_editor.css, EditorDialogCSSFileList[]=mugo_editor_dialog.css (if your own settings repeat them) | remove; set ezoe.ini [EditorSettings] CustomTagControls=enabled instead (L23) |
4.3 Permission defaults
LoveStack requires a policy for two things that an upgraded Exponential site keeps open. To keep LoveStack's behaviour, set both in your overrides:
Registration. Add to
settings/override/site.ini.append.php:[RoleSettings] PolicyOmitListExclude[]=user/registerand give the Anonymous role User / Register if visitors should still register (L02).
Node data calls. Add to
settings/override/ezjscore.ini.append.php:[ezjscServer_ezjscnode] RequirePolicy=enabledRoles that had ezjscore / call with
ezjscnodeunder LoveStack keep working (L01).
Step 5 — Database
Run Exponential's upgrade SQL for your engine, in order. LoveStack's schema starts from the legacy kernel's 5.4 schema, so both 6.0 files apply:
mysql mydatabase < update/database/mysql/6.0/dbupdate-5.4.0-6.0.0.sql mysql mydatabase < update/database/mysql/6.0/dbupdate-6.0.0-6.0.15.sqlFor PostgreSQL:
psql mydatabase < update/database/postgresql/6.0/dbupdate-5.4-to-6.0.sql psql mydatabase < update/database/postgresql/6.0/dbupdate-6.0.0-6.0.15.sqlThe columns LoveStack added (
ezuser.password_hashwith 255 characters,ezcontentobject_trash.trashed) are the same in Exponential and are not touched.Record the database as Exponential's:
./console exp:lovestack migrate # dry run: prints what it would write ./console exp:lovestack migrate --applyIt sets
ezsite_dataezpublish-versionfromlovestackto this release's version (6.0.15stable), which Exponential's upgrade check and about page read, and records LoveStack's schema version aslovestack-schema-version. LoveStack's owndb-schema-versionrow stays as a record. It never changes content, users or settings; a second run changes nothing; a database that does not come from LoveStack is refused. Below the rows it prints the settings and extensions still to change, from step 4.Keep what LoveStack's schema step 4 added. The unique index on
ezuser.loginstays: Exponential works with it, and new Exponential installations have it too (L04). Theezcontentobject_attribute.data_text NOT NULL DEFAULT ''column can stay as well: Exponential stores an empty string there, never NULL; the same content operations were tested on such a database and on an Exponential one with the same results.
Step 6 — Clear caches and check
php bin/php/ezpgenerateautoloads.php -e
php bin/php/ezcache.php --clear-all
./console exp:lovestack checkThe check should now end with OK. Then open the site and the administration, and check:
- the front page, a few content pages and a search;
- log in and out in the administration; edit and publish an object with an image;
var/log/error.logandvar/<site>/log/error.logstay quiet.
Step 7 — Your own PHP code
If your extensions call a LoveStack-only API, this is the Exponential one:
| LoveStack API | Exponential API |
|---|---|
eZURI::build( $url, $full ) | the same, plus $htmlEscape (L25) |
eZMailTransport::send( $mail, $transportType ) | the same (L26) |
eZTemplateDesignResource::setKeyValue( $key, $value, $override ) | the same (L31) |
eZSiteData::create(), fetchByName(), createNew() | the same |
fetch( 'content', 'site_data', … ) in templates | fetch( 'content', 'site_data', hash( 'name', … ) ) for names listed in site.ini [SiteDataSettings] TemplateReadable[] (L14) |
eZDebug::writeDeprecated(), eZDebug::LEVEL_DEPRECATED | the same (L07) |
{MyResolver} in a class name pattern, eZNamePatternResolver::instance() | the same pattern; the class implements expNamePatternResolverInterface and is listed in content.ini [NamePatternSettings] ResolverClasses[]; Exponential keeps the constructor and adds eZNamePatternResolver::resolve() (L18) |
eZDBInterface integer limits | MAX_INT, MIN_INT per driver and $db->clampInteger() (L34) |
rawurlencode / rawurldecode template operators | the same (L27) |
Find calls in your code:
grep -rnE "eZURI::build|setKeyValue\(|writeDeprecated|LEVEL_DEPRECATED|MAX_INT|MIN_INT|'site_data'|rawurl(en|de)code|eZNamePatternResolver::instance" \
extension/myextension design/mydesign --include=*.php --include=*.tplAbout LoveStack
LoveStack is developed by Mugo Web and published at https://github.com/mugoweb/ezpublish-legacy
and on Packagist as mugoweb/ezpublish-legacy.
Its own upgrade notes are in its
update/README.md.
Thanks to Mugo Web, whose documented schema steps (update/database/mysql/lovestack/1.sql to
4.sql) made it possible to recognise a LoveStack database this precisely.
Moving the other way, or running both, is not covered: the two projects share their origin but not their release lines.