migrating extensions to ez publish 5
DESCRIPTION
Webinar eZ Sessions #6TRANSCRIPT
A quick look at the Symfony2 Bundle systemMigrating extensions to eZ Publish 5
04/12/2023Presenter: Łukasz Serwatka Slide 2
Extending eZ Publish 5Presenter
Łukasz Serwatka
Product Management Technical Lead
@lserwatka
Working with eZ since 1st of March 2005 Over 10 years of experience with eZ Publish Former member of the Engineering team eZ Publish & Polish PHP Community Member Expert in mobile solutions (mobile applications & mobile strategies)
04/12/2023Presenter: Łukasz Serwatka Slide 3
Extending eZ Publish 5Preparation
Drivers for migration (challenges, requirements) - It is very important to understand the drivers behind a migration effort
Inventory of current environment - Creating a detailed summary of the current extension portfolio really helps in terms of understanding the scope of a migration effort
Migration service provider - evaluate at least a couple of migration service providers if you do not have migration skills and staff in-house.
Migration effort estimate - the estimate depends on many factors such as extension size, database complexity, components, etc. Usually provided by the migration service provider.
Training requirements - Training requirements for existing development team on the new platform need to be assessed to ensure that they can support the new environment effectively and can participate in the migration process if required.
04/12/2023Presenter: Łukasz Serwatka Slide 4
Extending eZ Publish 5Preparation
Make in-depth analysis of the existing eZ Publish 4.x extension functionality and code base, focusing especially on External storage (custom tables) Configuration (INI settings overrides) CLI scripts Template overrides Datatypes Edit handlers Workflow events AJAX calls Translations User interface (backend)
Carefully judge which elements can be natively implemented in eZ Publish 5 and which ones still require the legacy kernel. Not all legacy features are available in eZ Publish 5 yet, and it is an ongoing process to fill the gaps.
04/12/2023Presenter: Łukasz Serwatka Slide 5
Extending eZ Publish 5Preparation
The eZ Publish 5 supported extension points at the moment: FieldTypes (with custom tables) Templates (view providers for Content, Location and Blocks [since eZ Publish 5.1]) Services (Persistence API) Controllers & Actions (Routes) Events (PostSiteAccessMatchEvent, PreContentViewEvent,
APIContentExceptionEvent)- eZ/Publish/Core/MVC/Legacy/LegacyEvents.php- eZ/Publish/Core/MVC/Symfony/MVCEvents.php
04/12/2023Presenter: Łukasz Serwatka Slide 6
Extending eZ Publish 5New concepts in eZ Publish 5.x
eZ Publish 4.x eZ Publish 5.x
Module Controller, extends eZ\Bundle\EzPublishCoreBundle\Controller
Action & View Action, the method on the Controller to execute. View is a (Twig) template that displays the result of the Action.
eZTemplate Twig, new template engine, new syntax
fetch() Render function, HMVC concept, a function that enables embedding other controller calls
Extension Bundle in eZ Publish 5 (Symfony2)
CLI eZ Publish 5 ezpublish/console component for creating command line interfaces
INI settings YAML, recommended configuration type in eZ Publish 5
04/12/2023Presenter: Łukasz Serwatka Slide 7
Extending eZ Publish 5Naming differences between eZ Publish 4.x and 5.x
eZ Publish 4.x eZ Publish 5.x
(Content) Class ContentType
(Content) Class Group ContentTypeGroup
(Content) Class Attribute FieldDefinition
(Content) Object Content (meta info in: ContentInfo)
(Content Object) Version VersionInfo
(Content Object) Attribute Field
(Content Object) Attribute content FieldValue
Datatype FieldType
Node Location
04/12/2023Presenter: Łukasz Serwatka
eZ Publish 5 can be extended thanks to the bundle system A Bundle is a directory containing a set of files (PHP files, stylesheets,
JavaScripts, images, ...) that implement a single feature (a blog, a forum, etc) and which can be easily shared with other developers.
eZ Publish 5 also provides a command line interface for generating a basic bundle skeleton:$ php ezpublish/console generate:bundle –namespace=eZ/TestBundle
Slide 8
Extending eZ Publish 5
04/12/2023Presenter: Łukasz Serwatka Slide 9
Extending eZ Publish 5Bundle Directory Structure
Bundle Directory Structure Description
Controller/ contains the controllers of the bundle (e.g. HelloController.php);
DependencyInjection/ holds certain dependency injection extension classes, which may import service configuration
Resources/config/ houses configuration, including routing configuration (e.g. routing.yml);
Resources/views/ holds templates organized by controller name (e.g. Hello/index.html.twig);
Resources/public/ contains web assets (images, stylesheets, etc) and is copied or symbolically linked into the project web/ directory via the assets:install console command;
Tests/ holds all tests for the bundle.
04/12/2023Presenter: Łukasz Serwatka Slide 10
Extending eZ Publish 5Bundle Directory Structure – Advanced
Bundle Directory Structure Description
API/ contains the value object definitions, service interfaces, etc. In short, public API interfaces provided by your bundle.
Core/ holds field types implementation, persistence related classes, repository implementations, signal-slot implementations, etc.
SPI/ (Service Provider Interface) holds interfaces that can contain one or several implementations around Persistence (database), IO (file system), FieldTypes (formerly DataTypes), Limitations (permissions system), etc.
EventListeners/ holds event listener implementation for both eZ Publish 5 and LS
Command/ contains Console commands; each file must be suffixed with Command.php
04/12/2023Presenter: Łukasz Serwatka
Example eZ Publish 5 Bundle architecture
Slide 11
Extending eZ Publish 5Bundle Directory Structure
04/12/2023
File: eZTestBundle.php
<?php Namespace eZ\TestBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class eZTestBundle extends Bundle{}
Presenter: Łukasz Serwatka Slide 12
Extending eZ Publish 5Main Bundle Class
04/12/2023Presenter: <enter presenter in footnote>
Before a Bundle can be used it has to be registered in the system. With the registerBundles() method, you have total control over which bundles
are used by eZ Publish 5 (including the core Symfony bundles).// ezpublish/EzPublishKernel.phppublic function registerBundles(){ $bundles = array( ..., // register your bundles new eZ\TestBundle\eZTestBundle(), ); // ...
return $bundles;}
Slide 13
Extending eZ Publish 5Registering Bundle
04/12/2023Presenter: Łukasz Serwatka
eZ Publish 5 provides a shortcut for automatic bundle registration
php ezpublish/console generate:bundle --namespace=eZ/TestBundle
php ezpublish/console assets:install --symlink
php ezpublish/console cache:clear
Slide 14
Extending eZ Publish 5Registering Bundle
04/12/2023
File: eZTestBundle.php
<?php Namespace eZ\TestBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class eZTestBundle extends Bundle{ public function getParent() { return ’eZDemoBundle'; }}
Presenter: Łukasz Serwatka Slide 15
Extending eZ Publish 5Bundle Override
04/12/2023
File: src/eZ/DemoBundle/Controller/MyController.php<?phpnamespace eZ\DemoBundle\MyController;
use EzSystems\DemoBundle\Controller\DemoController as BaseController;
class MyController extends BaseController{ public function footerAction( $locationId ) { // Call parent method or completely replace its logic with your own
$response = parent::footerAction( $locationId );
// ... do custom stuff return $response; }}
Only works if the bundle refers to the controller using the standard EzSystemsDemoBundle:Demo:footer syntax in routes and templates
Presenter: Łukasz Serwatka Slide 16
Extending eZ Publish 5Controller Override
04/12/2023Presenter: Łukasz Serwatka
File: view.html.twig
<h1>Hello</h1><p>I’m a Twig template!</p>
Created Twig template can be included as follows:
{% include ‘eZTestBundle::view.html.twig’ %}
Slide 17
Extending eZ Publish 5Example Twig Template
04/12/2023Presenter: Łukasz Serwatka
Legacy template include
// eZ Publish 5.0{% ez_legacy_include "design:parts/menu.tpl" with {"current_node_id": location.contentInfo.mainLocationId} %}
// eZ Publish 5.1 and above{% include "design:parts/menu.tpl" with {"current_node_id": location.contentInfo.mainLocationId} %}
Note that if you pass a Content or a Location it will be converted to the corresponding eZ Publish Legacy objects.
Slide 18
Extending eZ Publish 5Working with legacy templates
04/12/2023Presenter: Łukasz Serwatka
The best practice for extension migration regarding configuration is to keep a compatible format
ezoe.ini[EditorSettings]# Skin for the editor, 'default' and 'o2k7' is included as standardSkin=o2k7# Lets you control alignment of toolbar buttons [left|right]ToolbarAlign=left
parameters: # Namespace is ezoe (INI file was ezoe.ini), scope is defined to ezdemo_site siteaccess ezoe.ezdemo_site.EditorSettings.Skin: o2k7 ezoe.ezdemo_site.EditorSettings.ToolbarAlign: left
Slide 19
Extending eZ Publish 5Working with INI settings
04/12/2023Presenter: Łukasz Serwatka
// Assuming that current siteaccess is ezdemo_site// The following code will work regardless of whether you are using the legacy extension or the migrated one.$resolver = $this->getConfigResolver();$skin = $resolver->getParameter( ’EditorSettings.Skin', ’ezoe' );$toolbarAlign= $resolver->getParameter( ’EditorSettings.ToolbarAlign', ’ezoe' );
Slide 20
Extending eZ Publish 5Working with INI settings
04/12/2023Presenter: Łukasz Serwatka
Datatypes are FieldTypes in eZ Publish 5 Extends eZ\Publish\Core\FieldType\FieldType class Uses Value objects for storing arbitrary data (extends eZ\Publish\Core\
FieldType\Value) Requires converters for field values in legacy storage (implements eZ\
Publish\Core\Persistence\Legacy\Content\FieldValue\Converter) A NULL Converter is available for developers’ convenience Uses gateways for getting data from external storage (custom tables)
Slide 21
Extending eZ Publish 5FieldType
04/12/2023Presenter: Łukasz Serwatka
A common issue when rendering legacy field type in eZ Publish 5 is the API_CONTENT_EXCEPTION
It occurs when the API throws an exception that could not be caught internally (missing field type, missing converter, internal error...)
For simple field types, declaration of a NULL converter is often a resolution
// Resources/config/fieldtypes.ymlezpublish.fieldType.ezsample.class: %ezpublish.fieldType.eznull.class%
ezpublish.fieldType.ezsample: class: %ezpublish.fieldType.ezsample.class% parent: ezpublish.fieldType arguments: [ ”ezsample" ] tags: - {name: ezpublish.fieldType, alias: ezsample}
Slide 22
Extending eZ Publish 5NULL Converter
04/12/2023Presenter: Łukasz Serwatka
// Resources/config/storage_engines.ymlezpublish.fieldType.ezsample.converter.class: %ezpublish.fieldType.eznull.converter.class%
ezpublish.fieldType.ezsample.converter: class: %ezpublish.fieldType.ezsample.converter.class% tags: - {name: ezpublish.storageEngine.legacy.converter, alias: ezsample, lazy: true, callback: '::create'}
Slide 23
Extending eZ Publish 5NULL Converter
04/12/2023Presenter: Łukasz Serwatka
Some FieldTypes require that you store data in the external data sources Possible through the eZ\Publish\SPI\FieldType\FieldStorage interface.
// Resources/config/fieldtypes.yml
parameters: ezpublish.fieldType.ezsample.externalStorage.class: eZ\Publish\Core\FieldType\Sample\SampleStorage services: ezpublish.fieldType.ezsample.externalStorage: class: %ezpublish.fieldType.ezsample.externalStorage.class% tags: - {name: ezpublish.fieldType.externalStorageHandler, alias: ezsample}
Slide 24
Extending eZ Publish 5External storage
04/12/2023Presenter: Łukasz Serwatka
It is recommended to use gateway-based storage Implement a gateway infrastructure and a registry for the gateways Possible through eZ\Publish\Core\FieldType\StorageGateway// Resources/config/fieldtypes.yml
parameters: ezpublish.fieldType.ezsample.storage_gateway.class: eZ\Publish\Core\FieldType\Sample\SampleStorage\Gateway\LegacyStorage services: ezpublish.fieldType.ezsample.storage_gateway: class: %ezpublish.fieldType.ezsample.storage_gateway.class% tags: - {name: ezpublish.fieldType.externalStorageHandler.gateway, alias: ezsample, identifier: LegacyStorage}
Slide 25
Extending eZ Publish 5External storage
04/12/2023Presenter: Łukasz Serwatka
abstract class Gateway extends StorageGateway{ /** * Stores data in the database based on the given field data * * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $versionInfo * @param \eZ\Publish\SPI\Persistence\Content\Field $field */ abstract public function storeFieldData( VersionInfo $versionInfo, Field $field );
/** * Gets data stored in the field * * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $versionInfo * @param \eZ\Publish\SPI\Persistence\Content\Field $field */ abstract public function getFieldData( VersionInfo $versionInfo, Field $field );
/** * Deletes field data for all $fieldIds in the version identified by * $versionInfo. * * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $versionInfo * @param array $fieldIds */ abstract public function deleteFieldData( VersionInfo $versionInfo, array $fieldIds );}
Slide 26
Extending eZ Publish 5External storage
04/12/2023Presenter: Łukasz Serwatka
/** * Deletes field data for all $fieldIds in the version identified by * $versionInfo. * * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $versionInfo * @param array $fieldIds */ public function deleteFieldData( VersionInfo $versionInfo, array $fieldIds ) { $connection = $this->getConnection();
$query = $connection->createDeleteQuery(); $query ->deleteFrom( … ) ->where(…)
$query->prepare()->execute(); }
Slide 27
Extending eZ Publish 5External storage
04/12/2023Presenter: Łukasz Serwatka
Possible to run some PHP code inside a sandbox through the runCallback() method
<?php// Declare use statements for the classes you may needuse eZINI; // Inside a controller extending eZ\Bundle\EzPublishCoreBundle\Controller$settingName = 'MySetting';$test = array( 'oneValue', 'anotherValue' );$myLegacySetting = $this->getLegacyKernel()->runCallback( function () use ( $settingName, $test ) { // Here you can reuse $settingName and $test variables inside the legacy context $ini = eZINI::instance( 'someconfig.ini' ); return $ini->variable( 'SomeSection', $settingName ); });
Slide 28
Extending eZ Publish 5Running legacy code
04/12/2023Presenter: Łukasz Serwatka
Stored in the Resources/translations/ directory of the bundle. Each translation file must be named according to the following path:
domain.locale.loader. For example Resources/translations/messages.fr.yml Keyword messages preferred over messages that are written in the language
of the default locale. For example $t = $translator->trans(’ez5.great'); YAML is the recommended configuration type Possible to dump messages into a file with ezpublish/console
$ php ezpublish/console translation:update --output-format=yml --dump-messages <locale> <bundle name>
Slide 29
Extending eZ Publish 5Translations
04/12/2023Presenter: Łukasz Serwatka
Commands should be placed under the Command/ folder inside your Bundle and file name must be suffixed with Command.php, e.g EzTestCommand.php
Class EzTestCommand extends ContainerAwareCommand{ protected function configure() { }
protected function execute(InputInterface $input, OutputInterface $output) { }}
Slide 30
Extending eZ Publish 5Console commands
04/12/2023Presenter: Łukasz Serwatka
Console command configuration
Class EzTestCommand extends ContainerAwareCommand{ protected function configure() { $this ->setName('demo:eztest') ->setDescription(’eZ Publish 5 Console Test') ->addArgument(’first', InputArgument::OPTIONAL, ’First argument') ->addOption(’second', null, InputOption::VALUE_NONE, ‘Option param') ; }}
Slide 31
Extending eZ Publish 5Console commands
04/12/2023Presenter: Łukasz Serwatka
Console command configuration
Class EzTestCommand extends ContainerAwareCommand{ protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument(’first'); if ($name) { $text = 'Hello '.$name; } if ($input->getOption(’second')) { $text = strtoupper($text); }
$output->writeln($text); }}
Slide 32
Extending eZ Publish 5Console commands
04/12/2023Presenter: Łukasz Serwatka
We recommend using composer (http://getcomposer.org) to install bundles Provide packages via https://packagist.org website for ease of distribution Configuration with composer.json
Slide 33
Extending eZ Publish 5Composer
04/12/2023Presenter: Łukasz Serwatka
{ "name": ”ez/testbundle", "description": “", "license": "GPL-2.0", "authors": [ { "name": ”eZ", "homepage": "http://ez.no" } ], "require": { "ezsystems/ezpublish-kernel": "dev-master" }, "minimum-stability": "dev", "autoload": { "psr-0": {”eZ\\TestBundle": ""} }, "target-dir": ”eZ/TestBundle"}
Slide 34
Extending eZ Publish 5composer.json