Helix Swarm Guide (2019.3)

Upgrade custom modules to work with Zend 3

Tip

You must test your custom modules on a test system before transferring them to your production system. This avoids any negative impact on the operation of your production system. If you have more than one custom module, the modules should all be tested at the same time on the same test system as this ensures that the modules operate correctly with each other and with Helix Swarm.

Tip

If you add or edit a module, Swarm will not use that change until the Swarm config cache has been deleted. For instructions on deleting the config cache, see Swarm config cache file delete.

Swarm 2019.1 uses the Zend 3 framework, previous Swarm versions used the Zend 2 framework. The move to Zend 3 is part of our commitment to move away from using versions of platforms that have reached End-of-Life (EOL).

If you have any custom Swarm modules that were created for Swarm 2018.3 or earlier you must update them so that they will work in Swarm 2019.1 and later.

The section describes the changes that you must make to your custom modules to enable them to work with Swarm 2019.1 and later, it includes:

Summary of changes for the Zend 3 Framework that impact Swarm

The following Zend 3 changes are important for Swarm custom modules:

  • Custom module file locations have changed to the PSR-4 standard locations shown below. For information on how this affects an existing custom module, see Custom module file locations.
  • config/
          custom.modules.config.php (new file, required)
    module/
          ModuleName/ (required)
                    config/ (required)
                          module.config.php (existing file, required)
                    src/ (php files here, required)
                       Controller/
                                 MyIndexController.php
                       ...
                       other directories (non-php files here, optional)
                       ...  
                    Module.php (existing file, required)
    
  • custom.modules.config.php: this is a new configuration file that tells Swarm which custom modules it should load. This gives you control over which modules Swarm loads and prevents modules from being loaded by mistake. For information about the content of the file, see custom.modules.config.php.
  • Previously Swarm checked the modules directory and used any modules it found there.

  • IndexControllers: Zend has deprecated the use of getServiceLocator() to get services. Your invokables definitions must be changed to factories and the factories that create the IndexControllers must inject services.
  • We recommend you follow the ::class description to avoid errors in string representation. For information on changing from invokables definitions to factories, see IndexControllers.

  • View Helpers Zend has deprecated the use of getServiceLocator() to get services. Your invokables definitions must be changed to factories and the factories that create the view helpers must inject the services.
  • We recommend you follow the ::class description to avoid errors in string representation. For instructions on changing from invokables definitions to factories, see View Helpers.

  • Routes are now defined in Zend\Router not Zend\Mvc\Router.
  • Your routes must be updated, see Routes.

  • Event listeners can now use a declarative model that passes events to the listeners.
  • Your event listeners should be changed to use the new declarative model. For instructions on changing the event listeners, see Event listeners.

    Note

    Your existing listeners will continue to work for Swarm 2019.1 if you want to keep using them but we strongly recommend you move your event listeners to use the declarative model.

Upgrade custom modules for Swarm 2019.1 and later

This section describes the changes that you need to make to a custom module to refactor it for the Zend 3 framework.

Tip

The new language features in PHP 7.x enable you to use [] as a shortcut for array().

Custom module file locations

The file locations for custom modules has changed to the PSR-4 standard location.

For Swarm 2018.3 and earlier the file locations are

module/
      MyModuleName/
                   config/
                          module.config.php
                   src/
                       MyModuleName/
                                    Controller/
                                               MyIndexController.php
                   Module.php

For Swarm 2019.1 and later the file locations are

Changes:

  • The custom.modules.config.php is a new file and is required, see custom.modules.config.php.
  • The Controller directory has moved up the file structure so that it is now in the module/MyModuleName/src directory.
  • The MyIndexController file has moved up the file structure so that it is now in the module/MyModuleName/src/Controller directory.
  • The MyModuleName directory under the src directory is no longer used.
config/
      custom.modules.config.php
module/
      MyModuleName/
                  config/
                         module.config.php
                  src/
                     Controller/
                               MyIndexController.php
                  Module.php

custom.modules.config.php

The custom.modules.config.php is a new file and is required.

Swarm uses this file to check which custom modules it should load. This gives you control over which modules Swarm loads and prevents modules from being loaded by mistake.

Create the custom.modules.config.php file if it does not already exist. Edit the file so that it contains the following details for each of your modules:

  • namespaces array: enter your custom module names and paths
  • return array : enter your custom module names

For example, if you have three modules called MyModuleName, AnotherModuleName, and NewModuleName the file content would look similar to:

<?php
\Zend\Loader\AutoloaderFactory::factory(
    array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                'MyModuleName'       => BASE_PATH . '/module/MyModuleName/src',
                'AnotherModuleName'  => BASE_PATH . '/module/AnotherModuleName/src',
                'NewModuleName'      => BASE_PATH . '/module/NewModuleName/src',
            )
        )
    )
);
return [
    'MyModuleName',
    'AnotherModuleName',
    'NewModuleName',
];

IndexControllers

Zend has deprecated the use of getServiceLocator() to get services. This means that your invokables must be changed to factories and the factory that creates the index controller must inject the services.

Tip

We recommend you follow the ::class description to avoid errors in string representation.

For Swarm 2018.3 and earlier the index controllers used invokables

'controllers' => array(
    'invokables' => array( 
        'MyModuleName\Controller\Index' => 'MyModuleName\Controller\IndexController'
    ),
),

For Swarm 2019.1 and later the index controllers must use factories

The IndexController should extend Application\Controller\AbstractIndexController, this means that the IndexControllerFactory can automatically inject the services . In this case you can use the Swarm IndexControllerFactory.

Change: Index controller refactored to use factories.

'controllers' => array(
    'factories' => [
        MyModuleName\Controller\IndexController::class => Application\Controller\IndexControllerFactory::class,
    ],
),

View Helpers

Zend has deprecated the use of getServiceLocator() to get services. This means that your invokables must be changed to factories and the factory that creates the view helper must inject the services.

Tip

We recommend you follow the ::class description to avoid errors in string representation.

For Swarm 2018.3 and earlier the view helpers use invokables definitions

'view_helpers' => array(
        'invokables' => array(
            'helper1' => 'MyModuleName\View\Helper\Helper1',
            'helper2' => 'MyModuleName\View\Helper\Helper2',
        ),
    ),

For Swarm 2019.1 and later the view helpers must use factories

In the following example, <YourHelperFactory> should construct the correct helper based on the name and inject services if needed. We recommend using ::class rather than arbitrary strings as this can limit the possibility of errors. The use of classes also makes your factory simpler because reflection can be used to construct the helpers if they all extend a common parent class.

Change: View helpers refactored to use factories.

'view_helpers' => array(
        'factories' => array_fill_keys(
            [
                MyModuleName\View\Helper\Helper1::class,
                MyModuleName\View\Helper\Helper2::class,
            ],
            <YourHelperFactory>::class
        )
    )

Routes

Update your routes in module.config.php to match the new controller definitions.

For Swarm 2018.3 and earlier routes would look similar to

'MyModuleName-message' => array(
                'type' => 'Zend\Mvc\Router\Http\Segment',
                'options' => array(
                    'route'    => '/MyModuleName/message[/]',
                    'defaults' => array(
                        'controller' => 'MyModuleName\Controller\Index',
                        'action'     => 'message'
                    ),
                ),
            ),

For Swarm 2019.1 and later routes must be changed to look similar to

Changes:

  • The route has been changed for 'type'
  • The route has been changed for 'controller'
'MyModuleName-message' => array(
                'type' => 'Zend\Router\Http\Segment',
                'options' => array(
                    'route'    => '/MyModuleName/message[/]',
                    'defaults' => array(
                        'controller' => MyModuleName\Controller\IndexController::class,
                        'action'     => 'message'
                    ),
                ),
            ),

Event listeners

Note

Your existing listeners will continue to work for Swarm 2019.1 if you want to keep using them but we strongly recommend you move your event listeners to use the declarative model.

We strongly recommend that you refactor your event listeners to use the declarative model because it has a number of advantages over the previous method:

  • AbstractEventListener provides common code for listeners to use
  • The declarative model offers better debug options (logging)
  • The declarative model is neater, easier to read, easier to support, and easier to maintain

Your listeners should extend Events\Listener\AbstractEventListener. This means that the ListenerFactory can create them without you having to write your own factory.

Tip

Look at the code in the AbstractEventListener.php file in module/events/src/Listener of Swarm 2019.1 and later to see the functions that are available to you.

For Swarm 2018.3 and earlier the event listeners look similar to

namespace MyModuleName;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $event)
{
$application = $event->getApplication();
$services = $application->getServiceManager();
$events = $services->get('queue')->getEventManager();

$events->attach(
'*',
function ($event) {
$mail = $event->getParam('mail');
if (!$mail || !isset($mail['htmlTemplate'], $mail['textTemplate'])) {
return;
}
}
-199
); } }

For Swarm 2019.1 and later when using the declarative structure the event listeners should look similar to

Changes:

  • New listener directory created in the MyModuleName directory, in the following example the directory is called Listener
  • New listener PHP file created in the listener directory, in this example it is called Listener.php
  • Edit the content of your module.config.php to configure your event listeners, this replaces the attach listener event functionality of the onBootstrap method in the original Module.php file.
namespace MyModuleName\Listener;

use Events\Listener\AbstractEventListener;
use Zend\EventManager\Event;

class Listener extends AbstractEventListener
{
    public function handleEmail(Event $event)
    {
        $mail = $event->getParam('mail');
        if (!$mail || !isset($mail['htmlTemplate'], $mail['textTemplate'])) {
            return;			
        }
    }
}

Further reading

Note

Swarm supports Zend version 3.2.0, features and functions in the Zend documentation that were introduced in later versions of Zend will not work with Swarm.