Helix Swarm Guide (2019.3)

Module overview

Important

The operation and testing of custom modules is the responsibility of the module creator.  Perforce Software, Inc. is not responsible for the operation of your custom modules, nor does Perforce Software, Inc. make any representations or warranties regarding the interoperability of your custom modules with Helix Swarm.

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.

A Swarm custom module is created in a folder in the modules folder of your Swarm installation. The folder name must match the custom module name and must contain at least a Module.php file and a module.config.php file. A custom module will not work in Swarm until you enable it. Enable your custom modules in Swarm by adding them to the custom.modules.config.php file in the config directory (a peer of the modules directory).

This chapter provides basic information about how custom modules integrate with Swarm and assumes a basic knowledge of the Zend framework. For more information about the Zend framework, see Zend 3 Quick Start documentation.

This section includes:

Upgrade existing custom modules to the Zend 3 framework

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. For instructions on updating modules to the Zend 3 framework, see Upgrade custom modules to work with Zend 3.

Influence activity events, emails, etc.

When something happens in Helix server (change submitted, files shelved, job added/edited), or state changes within Swarm (comment added, review state changed, etc.), the event is pushed onto the Swarm task queue. A background worker process pulls events off of the queue and publishes an event alerting modules about activity they may be interested in processing. This architecture allows the Swarm user interface to be fairly quick while accommodating tasks that might require notable processing time, or need to wait for related information to become available.

Subscribers to the worker event flesh the item out (fetch the change/job details, for example) and indicate if it should result in an activity entry, email notification, etc. By subscribing to various event topics, your custom module can pay attention to specific types of events. While your custom module is processing an event, it can modify the text of activity events, change the contents of emails, drop things entirely from activity, etc.

When your custom module subscribes to an event, set the priority to influence how early or late in the process it runs. You will likely want your module to run after most other modules have done their work to flesh out the event, but before Swarm's events module processes it. The events module is a good example of subscribing to these events:

swarm_install/module/Events/config/module.config.php

Tip

Note that its priority is set to -100. Select a value before that for your own module (for example, 0 would be neutral and -90 would indicate that you are interested in being last).

Event priority is from the highest positive number to the lowest negative number with 0 in the middle. For a full list of tasks and their event priorities, see Task details.

Task types

For details of each of the following tasks, see Task details.

  • task.commit
  • task.shelve
  • task.review
  • task.change
  • task.mail
  • task.cleanup.attachment
  • task.cleanup.archive
  • task.shelvedel
  • task.changesave
  • task.changesaved
  • task.comment
  • task.comment.batch
  • task.commentSendDelay
  • task.group
  • task.groupdel
  • task.job
  • task.user
  • task.userdel
  • task.workflow.created
  • task.workflow.updated

Templates

Override existing view templates using your custom module. Have a look at this example module that demonstrates how to customize the email templates Swarm uses for comment notifications.

For more information about views, see the Zend/View Quick Start.

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.

Custom module file locations

The custom module files must be stored using the PSR-4 standard locations shown below:

config/
      custom.modules.config.php (required)
module/
      ModuleName/ (required)
                config/ (required)
                      module.config.php (required)
                src/ (php files here, required)
                   Controller/
                             MyIndexController.php
                Listener/ (optional)
                        MyListener.php (optional)
                   ...
                   other directories (non-php files here, optional)
                   ...  
                Module.php (required)

IndexControllers

Create your IndexControllers using factories. The IndexControllers should extend Application\Controller\AbstractIndexController and use the Swarm IndexControllerFactory, this means that the IndexControllerFactory can automatically inject the services .

Tip

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

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

View helpers

Create your view helpers using factories. The factories that create the view helpers must inject any services that are required.

Tip

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.

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

Set options on existing helpers

It is possible to influence the behavior of existing view helpers by setting options on them; for an example see: swarm_install/module/Application/Module.php

Register new helpers

It is also possible to register new view helpers by placing them within your module's hierarchy, for example, MyModule/src/View/Helper/Foo.php. Use the following Swarm view helper for inspiration: swarm_install/module/Activity/src/View/Helper/Activity.php

Then register your view helper with the view manager via your ModuleConfig: swarm_root/module/Activity/config/module.config.php

Event listeners

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

The Listener.php file contains the implementation of your event listener and the module.config.php file configures your event listeners.

Tip
  • Look at the code in the AbstractEventListener.php file in module/events/src/Listener to see the functions that are available to you.
  • We strongly recommend that you create your event listeners to use the declarative model because it has a number of advantages over the non-declarative model:
    • 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

Example module.config.php file that uses the declarative model for event listeners:

Tip

Listener::class example details:

  • Events\Listener\ListenerFactory::ALL => [
  • We are listening to ALL here for convenience because we are listening for mail events but this means it will trigger on every event. Usually is better to just listen for the events you are interested in. For example, if you are interested in commits and shelves you would listen on COMMIT and SHELVE events.

  • Events\Listener\ListenerFactory::PRIORITY => -199,
  • Declares an event priority of -199 for the event listener because email delivery events are processed with a priority of -200 and the example event needs to run just before the email delivery event.

  • Events\Listener\ListenerFactory::CALLBACK => 'handleEmail',
  • Declares the function name within the listener class that is called.

  • Events\Listener\ListenerFactory::MANAGER_CONTEXT => 'queue'
  • Triggers your custom listener when Swarm processes the Swarm event queue.

<?php
/**
 * Perforce Swarm
 *
 * @copyright   2019 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
*/

$listeners = [EmailExample\Listener\Listener::class];
return [
    'listeners' => $listeners,
    'service_manager' =>[
        'factories' => array_fill_keys(
            $listeners,
            Events\Listener\ListenerFactory::class
        )
    ],
    Events\Listener\ListenerFactory::EVENT_LISTENER_CONFIG => [ 
        Events\Listener\ListenerFactory::ALL => [
            EmailExample\Listener\Listener::class => [
                [
                    Events\Listener\ListenerFactory::PRIORITY => -199,
                    Events\Listener\ListenerFactory::CALLBACK => 'handleEmail',
                    Events\Listener\ListenerFactory::MANAGER_CONTEXT => 'queue'
                ]
            ]
        ]
    ]
];		

Example of an email Listener.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;			
        }
    }
}

Enabling your custom modules

Swarm uses the custom.modules.config.php 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 in the config directory (a peer of the modules directory) 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',
];

Further reading

For detailed information about the Zend framework and examples see the following:

  • The Zend 3 Quick Start documentation and Zend 3 framework documentation portal, it is useful to have a basic knowledge of the Zend framework before you create your own modules. .
  • 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.

  • Example linkify module, a simple custom module that replaces a specific piece of text with a link for changelists, jobs, code review descriptions, comments, and activity entries.
  • Example email module, a simple custom module that makes Swarm use a custom email template when it sends out when a comment notification is sent out.
  • Swarm JIRA module, a simple module implementation within Swarm: swarm_install/module/Jira