- Documentation >
- Update and migration >
- Update from v1.13 and v2.x >
- Update database to v2.5
Update database to v2.5
4. Update the database
Before you start this procedure, make sure you have completed the previous step,
Updating the app to v2.5.
Caution
Always back up your data before running any database update scripts.
After updating the database, clear the cache.
Do not use --force
argument for mysql
/ psql
commands when performing update queries.
If there is any problem during the update, it is best if the query fails immediately, so you can fix the underlying problem before you execute the update again.
If you leave this for later you risk ending up with an incompatible database, though the problems might not surface immediately.
Note
If you are starting from version v2.2 or later, skip to the relevant section.
A. Update to v2.2
Change from UTF8 to UTF8MB4
In v2.2 the character set for MySQL/MariaDB database tables changes from utf8
to utf8mb4
to support 4-byte characters.
To apply this change, use the following database update script:
| mysql -u <username> -p <password> <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.1.0-to-7.2.0.sql
|
If you use DFS Cluster, also execute the following database update script:
| mysql -u <username> -p <password> <dfs_database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.1.0-to-7.2.0-dfs.sql
|
Be aware that these upgrade statements may fail due to index collisions.
This is because the indexes have been shortened, so duplicates may occur.
If that happens, you must remove the duplicates manually, and then repeat the statements that failed.
After successfully running those statements, change the character set and collation for each table, as described in kernel upgrade documentation.
You should also change the character set that is specified in the application config:
In app/config/config.yml
, set the following:
| doctrine:
dbal:
connections:
default:
charset: utf8mb4
|
Also make the corresponding change in app/config/dfs/dfs.yml
.
Migrate Landing Pages
To update to v2.2 with existing Landing Pages, you need to use a dedicated script.
The script is contained in the ezplatform-page-migration
bundle and works since version v2.2.2.
To use the script:
- Run
composer require ezsystems/ezplatform-page-migration
- Add the bundle to
app/AppKernel.php
: new EzSystems\EzPlatformPageMigrationBundle\EzPlatformPageMigrationBundle(),
- Run command
bin/console ezplatform:page:migrate
Tip
This script uses the layout defined in your Landing Page.
To migrate successfully, you need to copy your zone configuration
from ez_systems_landing_page_field_type
under ezplatform_page_fieldtype
in the new config.
Otherwise the script will encounter errors.
You can remove the bundle after the migration is complete.
The ezplatform:page:migrate
command migrates Landing Pages created in eZ Platform v1.x, v2.0 and v2.1 to new Pages.
The operation is transactional and rolls back in case of errors.
Block migration
In v2.2 Page Builder does not offer all blocks that Landing Page editor did. The removed blocks include Keyword, Schedule, and Form blocks.
The Places block has been removed from the clean installation and will only be available in the demo out of the box.
If you use this block in your site, re-apply its configuration based on the demo.
Later versions of Page Builder come with a Content Scheduler block and new Form Blocks, but migration of Schedule blocks to Content Scheduler blocks and of Form Blocks is not supported.
If there are missing block definitions, such as Form Block or Schedule Block,
you have an option to continue, but migrated Landing Pages will come without those blocks.
Tip
If you use different repositories with different SiteAccesses, use the --siteaccess
switch
to migrate them separately.
Tip
You can use the --dry-run
switch to test the migration.
After the migration is finished, you need to clear the cache.
Migrate layouts
The ez_block::renderBlockAction
controller used in layout templates has been replaced by EzPlatformPageFieldTypeBundle:Block:render
. This controller has two additional parameters, locationId
and languageCode
. Only languageCode
is required.
Also, the HTML class data-studio-zone
has been replaced with data-ez-zone-id
See documentation for an example on usage of the new controller.
Migrate custom blocks
Landing Page blocks (from v2.1 and earlier) were defined using a class implementing EzSystems\LandingPageFieldTypeBundle\FieldType\LandingPage\Model\AbstractBlockType
.
In Page Builder (from v2.2 onwards), this interface is no longer present. Instead the logic of your block must be implemented in a Listener.
Typically, what you previously would do in getTemplateParameters()
, you'll now do in the onBlockPreRender()
event handler.
The definition of block parameters has to be moved from createBlockDefinition()
to the YAML configuration for your custom blocks.
For more information about how custom blocks are implemented in Page Builder, have a look at Creating custom Page blocks for your custom blocks.
For the migration of blocks from Landing Page to Page Builder, you'll need to provide a converter for attributes of custom blocks. For simple blocks you can use \EzSystems\EzPlatformPageMigration\Converter\AttributeConverter\DefaultConverter
.
Custom converters must implement the \EzSystems\EzPlatformPageMigration\Converter\AttributeConverter\ConverterInterface
interface.
convert()
will parse XML \DOMNode $node
and return an array of \EzSystems\EzPlatformPageFieldType\FieldType\LandingPage\Model\Attribute
objects.
Below is an example of a simple converter for a custom block:
| app.block.foobar.converter:
class: EzSystems\EzPlatformPageMigration\Converter\AttributeConverter\DefaultConverter
tags:
- { name: ezplatform.fieldtype.ezlandingpage.migration.attribute.converter, block_type: foobar }
|
Notice service tag ezplatform.fieldtype.ezlandingpage.migration.attribute.converter
that must be used for attribute converters.
This converter is only needed when running the ezplatform:page:migrate
script and can be removed once that has completed.
Page migration example
Below is an example how to migrate a Landing Page Layout and Block to new Page Builder. The code is based on the Random block
defined in the Enterprise Beginner tutorial
Landing Page code
app/Resources/views/layouts/sidebar.html.twig
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | <div data-studio-zones-container>
<main class="landing-page__zone landing-page__zone--{{ zones[0].id }} landing-page__zone--left col-xs-8" data-studio-zone="{{ zones[0].id }}">
{% if zones[0].blocks %}
{% for block in zones[0].blocks %}
<div class="landing-page__block block_{{ block.type }}">
{{ render_esi(controller('ez_block::renderBlockAction', {
'contentId': contentInfo.id,
'blockId': block.id,
'versionNo': versionInfo.versionNo
})) }}
</div>
{% endfor %}
{% endif %}
</main>
<aside class="landing-page__zone landing-page__zone--{{ zones[1].id }} landing-page__zone--left col-xs-4" data-studio-zone="{{ zones[1].id }}">
{% if zones[1].blocks %}
{% for block in zones[1].blocks %}
<div class="landing-page__block block_{{ block.type }}">
{{ render_esi(controller('ez_block::renderBlockAction', {
'contentId': contentInfo.id,
'blockId': block.id,
'versionNo': versionInfo.versionNo
})) }}
</div>
{% endfor %}
{% endif %}
</aside>
</div>
|
app/config/layouts.yml
:
1
2
3
4
5
6
7
8
9
10
11
12
13 | ez_systems_landing_page_field_type:
layouts:
sidebar:
identifier: sidebar
name: Right sidebar
description: Main section with sidebar on the right
thumbnail: assets/images/layouts/sidebar.png
template: layouts/sidebar.html.twig
zones:
first:
name: First zone
second:
name: Second zone
|
src/AppBundle/Block/RandomBlock.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 | <?php
namespace AppBundle\Block;
use EzSystems\LandingPageFieldTypeBundle\Exception\InvalidBlockAttributeException;
use EzSystems\LandingPageFieldTypeBundle\FieldType\LandingPage\Definition\BlockDefinition;
use EzSystems\LandingPageFieldTypeBundle\FieldType\LandingPage\Definition\BlockAttributeDefinition;
use EzSystems\LandingPageFieldTypeBundle\FieldType\LandingPage\Model\AbstractBlockType;
use EzSystems\LandingPageFieldTypeBundle\FieldType\LandingPage\Model\BlockValue;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\SearchService;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
class RandomBlock extends AbstractBlockType
{
/**
* Content ID regular expression.
*
* @example 16
*
* @var string
*/
const PATTERN_CONTENT_ID = '/[0-9]+/';
/** @var \eZ\Publish\API\Repository\LocationService */
private $locationService;
/** @var \eZ\Publish\API\Repository\ContentService */
private $contentService;
/** @var \eZ\Publish\API\Repository\SearchService */
private $searchService;
/**
* @param \eZ\Publish\API\Repository\LocationService $locationService
* @param \eZ\Publish\API\Repository\ContentService $contentService
* @param \eZ\Publish\API\Repository\SearchService $searchService
*/
public function __construct(
LocationService $locationService,
ContentService $contentService,
SearchService $searchService
) {
$this->locationService = $locationService;
$this->contentService = $contentService;
$this->searchService = $searchService;
}
public function getTemplateParameters(BlockValue $blockValue)
{
$attributes = $blockValue->getAttributes();
$contentInfo = $this->contentService->loadContentInfo($attributes['parentContentId']);
$randomContent = $this->getRandomContent(
$this->getQuery($contentInfo->mainLocationId)
);
return [
'content' => $randomContent,
];
}
/**
* Returns random picked Content.
*
* @param \eZ\Publish\API\Repository\Values\Content\LocationQuery $query
*
* @return \eZ\Publish\API\Repository\Values\Content\Content
*/
private function getRandomContent(LocationQuery $query)
{
$results = $this->searchService->findLocations($query);
$searchHits = $results->searchHits;
if (count($searchHits) > 0) {
shuffle($searchHits);
return $this->contentService->loadContentByContentInfo(
$searchHits[0]->valueObject->contentInfo
);
}
return null;
}
/**
* Returns LocationQuery object based on given arguments.
*
* @param int $parentLocationId
*
* @return \eZ\Publish\API\Repository\Values\Content\LocationQuery
*/
private function getQuery($parentLocationId)
{
$query = new LocationQuery();
$query->query = new Criterion\LogicalAnd([
new Criterion\Visibility(Criterion\Visibility::VISIBLE),
new Criterion\ParentLocationId($parentLocationId),
]);
return $query;
}
public function createBlockDefinition()
{
return new BlockDefinition(
'random',
'Random',
'default',
'assets/images/blocks/random_block.svg',
[],
[
new BlockAttributeDefinition(
'parentContentId',
'Parent',
'embed',
self::PATTERN_CONTENT_ID,
'Choose a valid ContentID',
true,
false,
[],
[]
),
]
);
}
public function checkAttributesStructure(array $attributes)
{
if (!isset($attributes['parentContentId']) || preg_match(self::PATTERN_CONTENT_ID, $attributes['parentContentId']) !== 1) {
throw new InvalidBlockAttributeException('Parent container', 'parentContentId', 'Parent ContentID must be defined.');
}
}
}
|
src/AppBundle/DependencyInjection/AppExtension.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | <?php
namespace AppBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Config\Resource\FileResource;
class AppExtension extends Extension implements PrependExtensionInterface
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__ . '/../Resources/config')
);
$loader->load('services.yml');
}
public function prepend(ContainerBuilder $container)
{
$configFile = __DIR__ . '/../Resources/config/blocks.yml';
$config = Yaml::parse(file_get_contents($configFile));
$container->prependExtensionConfig('ez_systems_landing_page_field_type', $config);
$container->addResource(new FileResource($configFile));
}
}
|
src/AppBundle/Resources/config/blocks.yml
:
| blocks:
random:
views:
random:
template: AppBundle:blocks:random.html.twig
name: Random Content Block View
|
src/AppBundle/Resources/config/services.yml
:
| services:
app.block.random:
class: AppBundle\Block\RandomBlock
arguments:
- '@ezpublish.api.service.location'
- '@ezpublish.api.service.content'
- '@ezpublish.api.service.search'
tags:
- { name: landing_page_field_type.block_type, alias: random }
|
Corresponding Page Builder code
app/Resources/views/layouts/sidebar.html.twig
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | <div data-studio-zones-container>
<main class="landing-page__zone landing-page__zone--{{ zones[0].id }} landing-page__zone--left col-xs-8" data-studio-zone="{{ zones[0].id }} data-ez-zone-id="{{ zones[0].id }}">
{% if zones[0].blocks %}
{% set locationId = parameters.location is not null ? parameters.location.id : contentInfo.mainLocationId %}
{% for block in zones[0].blocks %}
<div class="landing-page__block block_{{ block.type }} data-ez-block-id="{{ block.id }}">
{{ render_esi(controller('EzPlatformPageFieldTypeBundle:Block:render', {
'locationId': locationId,
'contentId': contentInfo.id,
'blockId': block.id,
'versionNo': versionInfo.versionNo,
'languageCode': field.languageCode
})) }}
</div>
{% endfor %}
{% endif %}
</main>
<aside class="landing-page__zone landing-page__zone--{{ zones[1].id }} landing-page__zone--left col-xs-4" data-studio-zone="{{ zones[1].id }} data-ez-zone-id="{{ zones[1].id }}">
{% if zones[1].blocks %}
{% set locationId = parameters.location is not null ? parameters.location.id : contentInfo.mainLocationId %}
{% for block in zones[1].blocks %}
<div class="landing-page__block block_{{ block.type }} data-ez-block-id="{{ block.id }}">
{{ render_esi(controller('EzPlatformPageFieldTypeBundle:Block:render', {
'locationId': locationId,
'contentId': contentInfo.id,
'blockId': block.id,
'versionNo': versionInfo.versionNo,
'languageCode': field.languageCode
})) }}
</div>
{% endfor %}
{% endif %}
</aside>
</div>
|
app/config/layouts.yml
:
1
2
3
4
5
6
7
8
9
10
11
12
13 | ezplatform_page_fieldtype:
layouts:
sidebar:
identifier: sidebar
name: Right sidebar
description: Main section with sidebar on the right
thumbnail: assets/images/layouts/sidebar.png
template: layouts/sidebar.html.twig
zones:
first:
name: First zone
second:
name: Second zone
|
src/AppBundle/Block/Event/Listener/RandomBlockListener.php
in place of src/AppBundle/Block/RandomBlock.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 | <?php
namespace AppBundle\Block\Event\Listener;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\SearchService;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use EzSystems\EzPlatformPageFieldType\FieldType\Page\Block\Renderer\BlockRenderEvents;
use EzSystems\EzPlatformPageFieldType\FieldType\Page\Block\Renderer\Event\PreRenderEvent;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class RandomBlockListener implements EventSubscriberInterface
{
/** @var \eZ\Publish\API\Repository\ContentService */
private $contentService;
/**
* @var LocationService
*/
private $locationService;
/**
* @var SearchService
*/
private $searchService;
/**
* BannerBlockListener constructor.
*
* @param \eZ\Publish\API\Repository\ContentService $contentService
*/
public function __construct(
ContentService $contentService,
LocationService $locationService,
SearchService $searchService
) {
$this->contentService = $contentService;
$this->locationService = $locationService;
$this->searchService = $searchService;
}
/**
* @return array The event names to listen to
*/
public static function getSubscribedEvents()
{
return [
BlockRenderEvents::getBlockPreRenderEventName('random') => 'onBlockPreRender',
];
}
/**
* @param \EzSystems\EzPlatformPageFieldType\FieldType\Page\Block\Renderer\Event\PreRenderEvent $event
*
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
*/
public function onBlockPreRender(PreRenderEvent $event)
{
//BlockDefinitionFactory
$blockValue = $event->getBlockValue();
$renderRequest = $event->getRenderRequest();
$contentInfo = $this->contentService->loadContentInfo($blockValue->getAttribute('parentContentId')->getValue());
$randomContent = $this->getRandomContent(
$this->getQuery($contentInfo->mainLocationId)
);
$parameters = $renderRequest->getParameters();
$parameters['content'] = $randomContent;
$renderRequest->setParameters($parameters);
}
/**
* Returns random picked Content.
*
* @param \eZ\Publish\API\Repository\Values\Content\LocationQuery $query
*
* @return \eZ\Publish\API\Repository\Values\Content\Content
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
private function getRandomContent(LocationQuery $query)
{
$results = $this->searchService->findLocations($query);
$searchHits = $results->searchHits;
if (count($searchHits) > 0) {
shuffle($searchHits);
return $this->contentService->loadContentByContentInfo(
$searchHits[0]->valueObject->contentInfo
);
}
return null;
}
/**
* Returns LocationQuery object based on given arguments.
*
* @param int $parentLocationId
*
* @return \eZ\Publish\API\Repository\Values\Content\LocationQuery
*/
private function getQuery($parentLocationId)
{
$query = new LocationQuery();
$query->query = new Criterion\LogicalAnd([
new Criterion\Visibility(Criterion\Visibility::VISIBLE),
new Criterion\ParentLocationId($parentLocationId),
]);
return $query;
}
}
|
src/AppBundle/DependencyInjection/AppExtension.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | <?php
namespace AppBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Config\Resource\FileResource;
class AppExtension extends Extension implements PrependExtensionInterface
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__ . '/../Resources/config')
);
$loader->load('services.yml');
}
public function prepend(ContainerBuilder $container)
{
$configFile = __DIR__ . '/../Resources/config/blocks.yml';
$config = Yaml::parse(file_get_contents($configFile));
$container->prependExtensionConfig('ezplatform_page_fieldtype', $config);
$container->addResource(new FileResource($configFile));
}
}
|
src/AppBundle/Resources/config/blocks.yml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | blocks:
random:
name: Random
category: default
thumbnail: assets/images/layouts/sidebar.png
#configuration_template: blocks/random_config.html.twig
views:
random:
template: AppBundle:blocks:random.html.twig
name: Random Content Block View
attributes:
parentContentId:
type: embed
name: Parent Location ID
validators:
not_blank:
message: Please provide parent node
|
src/AppBundle/Resources/config/services.yml
:
1
2
3
4
5
6
7
8
9
10
11
12 | services:
_defaults:
autowire: true
autoconfigure: true
public: false
AppBundle\Block\Event\Listener\RandomBlockListener: ~
app.block.random.converter:
class: EzSystems\EzPlatformPageMigration\Converter\AttributeConverter\DefaultConverter
tags:
- { name: ezplatform.fieldtype.ezlandingpage.migration.attribute.converter, block_type: random }
|
B. Update to v2.3
Database update script
Apply the following database update script:
| mysql -u <username> -p <password> <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.2.0-to-7.3.0.sql
|
In an Enterprise installation, to create the Forms container under the content tree root use the following command:
| php bin/console ezplatform:form-builder:create-forms-container
|
You can also specify content type, Field values and language code of the container, for example:
| php bin/console ezplatform:form-builder:create-forms-container --content-type custom --field title --value 'My Forms' --field description --value 'Custom container for the forms' --language-code eng-US
|
You also need to run a script to add database tables for the Form Builder.
You can find it in https://github.com/ezsystems/ezplatform-ee-installer/blob/2.3/Resources/sql/schema.sql#L136
Form (ezform) Field Type
After the update, in order to create forms, you have to add a new content type (for example, named "Form") that contains Form
Field (this content type can contain other fields
as well). After that you can use forms inside Landing Pages via Embed block.
C. Update to v2.4
Workflow
When updating an Enterprise installation, you need to run a script
to add database tables for the Editorial Workflow.
The built-in Forms folder is located in the Form Section in versions 2.4+.
If you are updating your Enterprise installation, you need to add this Section manually and move the folder to it.
To allow anonymous users to access Forms, you also need to add the content/read
Policy
with the Form Section to the Anonymous User.
v2.4 changed the way of configuring custom tags. They are no longer configured under the ezpublish
key,
but one level higher in the YAML structure:
| ezpublish:
system:
<siteaccess>:
fieldtypes:
ezrichtext:
custom_tags: [exampletag]
ezrichtext:
custom_tags:
exampletag:
# ...
|
The old configuration is deprecated, so if you use custom tags, you need to modify your config accordingly.
D. Update to v2.5
Database update script
Apply the following database update script:
| mysql -u <username> -p <password> <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.4.0-to-7.5.0.sql
|
v2.5.3
To update to v2.5.3, additionally run the following script:
| mysql -u <username> -p <password> <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.5.2-to-7.5.3.sql
|
v2.5.6
To update to v2.5.6, additionally run the following script:
| mysql -u <username> -p <password> <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.5.4-to-7.5.5.sql
|
or for PostgreSQL:
| psql <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/postgres/dbupdate-7.5.4-to-7.5.5.sql
|
v2.5.9
To update to v2.5.9, additionally run the following script:
| mysql -u <username> -p <password> <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/mysql/dbupdate-7.5.6-to-7.5.7.sql
|
or for PostgreSQL:
| psql <database_name> < vendor/ezsystems/ezpublish-kernel/data/update/postgres/dbupdate-7.5.6-to-7.5.7.sql
|
Additionally, reindex the content:
| php bin/console ezplatform:reindex
|
Changes to database schema
The introduction of support for PostgreSQL includes a change in the way database schema is generated.
It is now created based on YAML configuration, using the new DoctrineSchemaBundle
.
If you are updating your application according to the usual procedure, no additional actions are required.
However, if you do not update your meta-repository, you need to take two additional steps:
- enable
EzSystems\DoctrineSchemaBundle\DoctrineSchemaBundle()
in AppKernel.php
- add
ez_doctrine_schema
configuration
Changes to Matrix Field Type
To migrate your content from legacy XML format to a new ezmatrix
value use the following command:
| bin/console ezplatform:migrate:legacy_matrix
|
Required manual cache clearing if using Redis
If you are using Redis as your persistence cache storage you should always clear it manually after an upgrade.
You can do it in two ways, by using redis-cli
and executing the following command:
or by executing the following command:
| bin/console cache:pool:clear cache.redis
|
Updating to 2.5.3
Page Builder
This step is only required when updating an Enterprise installation from versions higher than v2.2 and lower than v2.5.3.
In case of versions lower than 2.2, skip this step or ignore the information that indexes from a script below already exist.
When updating to v2.5.3, you need to run the following SQL commands to add missing indexes:
| CREATE INDEX ezpage_map_zones_pages_zone_id ON ezpage_map_zones_pages(zone_id);
CREATE INDEX ezpage_map_zones_pages_page_id ON ezpage_map_zones_pages(page_id);
CREATE INDEX ezpage_map_blocks_zones_block_id ON ezpage_map_blocks_zones(block_id);
CREATE INDEX ezpage_map_blocks_zones_zone_id ON ezpage_map_blocks_zones(zone_id);
CREATE INDEX ezpage_map_attributes_blocks_attribute_id ON ezpage_map_attributes_blocks(attribute_id);
CREATE INDEX ezpage_map_attributes_blocks_block_id ON ezpage_map_attributes_blocks(block_id);
CREATE INDEX ezpage_blocks_design_block_id ON ezpage_blocks_design(block_id);
CREATE INDEX ezpage_blocks_visibility_block_id ON ezpage_blocks_visibility(block_id);
CREATE INDEX ezpage_pages_content_id_version_no ON ezpage_pages(content_id, version_no);
|
Updating to 2.5.16
In order to promote use of eZ Platform, ezsystems/ez-support-tools
v1.0.10, as of eZ Platform v2.5.16, sets the Powered-By header.
It is enabled by default and generates a header like Powered-By: eZ Platform Enterprise v2
.
To omit the version number, use the following configuration:
| ezplatform_support_tools:
system_info:
powered_by:
release: "none"
|
To opt out of the whole feature, disable it with the following configuration:
| ezplatform_support_tools:
system_info:
powered_by:
enabled: false
|
Updating to v2.5.18
To update to v2.5.18, if you are using MySQL, additionally run the following update SQL command:
| ALTER TABLE ezpage_attributes MODIFY value LONGTEXT;
|
Update entity managers
Version v2.5.18 introduces new entity managers.
To ensure that they work in multi-repository setups, you must update the GraphQL schema.
You do this manually by following this procedure:
-
Update your project to v2.5.18 and run the php bin/console cache:clear
command to generate the service container.
-
Run the following command to discover the names of the new entity managers.
Take note of the names that you discover:
php bin/console debug:container --parameter=doctrine.entity_managers --format=json | grep ibexa_
-
For every entity manager prefixed with ibexa_
, run the following command:
php bin/console doctrine:schema:update --em=<ENTITY_MANAGER_NAME> --dump-sql
-
Review the queries and ensure that there are no harmful changes that could affect your data.
-
For every entity manager prefixed with ibexa_
, run the following command to run queries on the database:
php bin/console doctrine:schema:update --em=<ENTITY_MANAGER_NAME> --force
VCL configuration for Fastly
If you use Fastly, deploy the most up-to-date VCL configuration.
Locate the vendor/ezsystems/ezplatform-http-cache-fastly/fastly/ez_main.vcl
file, make sure that it has been updated with the following changes, and upload it to your Fastly:
| if (req.restarts == 0 && resp.status == 301 && req.http.x-fos-original-url) {
set resp.http.location = regsub(resp.http.location, "/_fos_user_context_hash", req.http.x-fos-original-url);
}
|
- Move the
#FASTLY recv
macro call to a new location, right after the Preserve X-Forwarded-For in all requests
section.
Optimize workflow queries
Run the following SQL queries to optimize workflow performance:
| CREATE INDEX idx_workflow_co_id_ver ON ezeditorialworkflow_workflows(content_id, version_no);
CREATE INDEX idx_workflow_name ON ezeditorialworkflow_workflows(workflow_name);
|
5. Finish the update
If you are hosting your site on Ibexa Cloud be aware of the fact that Varnish is enabled by default as of v1.13.5, v2.4.3 and v2.5.0.
If you are using Fastly, read about how to disable Varnish.
B. Dump assets
Dump web assets if you are using the prod
environment. In dev
this happens automatically:
| yarn install
yarn encore prod
|
If you encounter problems, additionally clear the cache and install assets:
| php bin/console cache:clear -e prod
php bin/console assets:install --symlink -e prod
yarn install
yarn encore prod
|
C. Commit, test and merge
When you resolve all conflicts and update composer.lock
, commit the merge.
You may or may not keep composer.lock
, depending on your version management workflow.
If you do not want to keep it, run git reset HEAD composer.lock
to remove it from the changes.
Run git commit
, and adapt the message if necessary.
Go back to master
, and merge the update-2.5
branch:
| git checkout master
git merge update-2.5
|
Insecure password hashes
To ensure that no users have unsupported, insecure password hashes, run the following command:
| # In v1 and v2:
php bin/console ezplatform:user:validate-password-hashes
# In v3:
php bin/console ibexa:user:validate-password-hashes
|
This command checks if all user hashes are up-to-date and informs you if any of them need to be updated.
D. Complete the update
Complete the update by running the following commands:
| # In v2.5:
php bin/console ezplatform:graphql:generate-schema
# In v3:
php bin/console ibexa:graphql:generate-schema
composer run post-install-cmd
|
Notify support
Please tell support that you have updated your installation. They will update your support portal to match the new version.
This ensures that you receive notifications about new maintenance releases and security advisories for the correct version.
You can contact support at support@ibexa.co or through your Support portal.
defaultLayout
setting not available
If you migrated you installation from eZ Publish Platform,
in Page Builder you can encounter an issue where the Default layout dropdown is disabled
with a "Layout '' for setting 'defaultLayout' is not available" error message.
If this happens, add the following temporary configuration to app/config/ezplatform.yml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | ezpublish:
system:
global:
ezpage:
layouts:
GlobalZoneLayout:
name: Global zone layout
template: globalzonelayout.tpl
2ZonesLayout1:
name: 2 zones (layout 1)
template: 2zoneslayout1.tpl
2ZonesLayout2:
name: 2 zones (layout 2)
template: 2zoneslayout2.tpl
2ZonesLayout3:
name: 2 zones (layout 3)
template: 2zoneslayout3.tpl
3ZonesLayout1:
name: 3 zones (layout 1)
template: 3zoneslayout1.tpl
3ZonesLayout2:
name: 3 zones (layout 2)
template: 3zoneslayout2.tpl
CallForActionLayout:
name: Call For Action zone layout
template: callforactionlayout.tpl
|
Clear the cache and refresh the page. The dropdown should now be active.
Select any option in the dropdown and save the content type.
You should now be able to remove the Field definition from the content type.
Afterwards, you can remove the configuration above from ezplatform.yml
.
Update to v3.3
It is strongly recommended to also update to the latest LTS, v3.3.