モジュールの概要

重要

カスタムモジュールの動作確認とテストは、そのモジュールの作成者が行う必要があります。Perforce Software, Inc.は、お客様が作成したカスタムモジュールの動作について責任を負うことはありません。またPerforce Software, Inc.は、お客様が作成したカスタムモジュールとHelix Swarmとの相互運用性について、一切保証することはありません。

ヒント

実稼働システムに移行する前に、必ずテストシステム上でカスタムモジュールのテストを行ってください。これにより、実稼働システムの運用に悪影響が及ぶことを防ぐことができます。複数のカスタムモジュールがある場合、すべてのモジュールを同時に同じテストシステム上でテストしてください。これにより、お互いに、そしてHelix Swarmと連携して、正しく運用できることを確認できます。

ヒント

モジュールの追加や編集を行った場合、構成キャッシュを再ロードするまで、そのモジュールがSwarmで使用されることはありません。構成キャッシュを再ロードすると、そのモジュールがSwarmで強制的に使用されます。Swarm構成キャッシュを再ロードするには、admin ユーザまたはsuper ユーザでなくてはなりません。[ユーザID]ドロップダウンメニューに移動して[システム情報]を選択し、[キャッシュ情報]タブをクリックしてから[構成の再ロード]ボタンボタンをクリックします。

Swarmカスタムモジュールが、Swarmインストール場所のmodulesフォルダに作成されます。フォルダ名は、カスタムモジュール名に一致する必要があり、最低限Module.phpファイルとmodule.config.phpファイルを含む必要があります。カスタムモジュールは、有効にするまで、Swarmで機能しません。Swarmでカスタムモジュールを有効にするには、それらのモジュールをconfigディレクトリ(modulesディレクトリに対応するディレクトリ)のcustom.modules.config.phpファイルに追加します。

この章では、カスタムモジュールがSwarmと統合する仕組みに関する基本的な情報について説明します。Laminas Frameworkの基礎知識が必要になります。Laminas Frameworkの詳細については、Laminasクイックスタートドキュメンテーションを参照してください。

このセクションには、次の内容が含まれます。

既存のカスタムモジュールをLaminas Frameworkにアップグレードする

バージョン2020.1以降のSwarmでは、Laminas Frameworkが使用されます。古いバージョンのSwarmでは、Zend Frameworkが使用されていました。Laminasへの移行は、サポート終了(EOL)になったバージョンのプラットフォームを使用しないようにするための措置です。

バージョン2019.3以前のSwarm用に作成されたカスタムのSwarmモジュールを使用している場合、バージョン2020.1以降のSwarmでも機能するように、そのモジュールを更新する必要があります。必要な更新操作は、カスタムモジュールを作成したSwarmのバージョン(アップグレードする前のSwarmのバージョン)によって異なります。

バージョン2019.1、2019.2、2019.3のSwarmで作成されたカスタムモジュールの場合

注意

実稼働システムに移行する前に、必ずテストシステム上でカスタムモジュールのテストを行ってください。これにより、実稼働システムの運用に悪影響が及ぶことを防ぐことができます。複数のカスタムモジュールがある場合、すべてのモジュールを同時に同じテストシステム上でテストしてください。これにより、お互いに、そしてHelix Swarmと連携して、正しく運用できることを確認できます。

バージョン2019.1、2019.2、2019.3のSwarmで作成されたカスタムモジュールではZend 3 Frameworkが使用されているため、Laminas Frameworkに移行してから、バージョン2020.1以降のSwarmで使用する必要があります。

  1. カスタムのZend 3モジュールをLaminas Frameworkに移行します。これを行うには、カスタムのZend 3モジュールが保管されているフォルダで、Laminas移行ツールを指すように設定を変更します。この移行ツールの詳細と、カスタムのZend 3モジュールをLaminasに移行する方法については、https://docs.laminas.dev/migration/を参照してください。
  2. Swarmの構成キャッシュを削除しない限り、移行後のカスタムモジュールがSwarmで使用されることはありません。構成キャッシュの削除方法については、「Swarm構成キャッシュファイルの削除」を参照してください。
  3. 移行後のカスタムモジュールが正しく機能することを確認してから、そのモジュールを本番環境のシステムに移行します。

バージョン2018.3以前のSwarmで作成されたカスタムモジュールの場合

注意

実稼働システムに移行する前に、必ずテストシステム上でカスタムモジュールの更新とテストを行ってください。これにより、実稼働システムの運用に悪影響が及ぶことを防ぐことができます。複数のカスタムモジュールがある場合、すべてのモジュールを同時に同じテストシステム上でテストしてください。これにより、お互いに、そしてHelix Swarmと連携して、正しく運用できることを確認できます。

バージョン2018.3以前のSwarmで作成されたカスタムモジュールではZend 2 Frameworkが使用されているため、Laminas Frameworkに移行してから、バージョン2020.1以降のSwarmで使用する必要があります。

  1. Zend 2のカスタムモジュールをZend 3 Frameworkに変換する方法については、「カスタムモジュールをアップグレードしてZend 3に対応させる」を参照してください。
  2. ヒント

    LaminasはZend 3 Frameworkをベースとしているため、比較的簡単にZend 3のカスタムモジュールをLaminas Frameworkに変換することができます。

    • 使用しているカスタムモジュールが1つか2つだけの場合、Zend 2をZend 3に変換してから、モジュール内のすべてのZendの参照を手動でLaminasに変更してもかまいません。この場合、Laminasへの移行ステップを実行する必要はありません。
    • 使用しているカスタムモジュールの数が多い場合は、以下の手順に記載されているLaminas移行ツールを実行して、カスタムモジュール内のすべての参照を自動的に変更した方が効率的です。

  3. カスタムのZend 3モジュールをLaminas Frameworkに移行します。これを行うには、カスタムのZend 3モジュールが保管されているフォルダで、Laminas移行ツールを指すように設定を変更します。この移行ツールの詳細と、カスタムのZend 3モジュールをLaminasに移行する方法については、https://docs.laminas.dev/migration/を参照してください。
  4. Swarmの構成キャッシュを削除しない限り、移行後のカスタムモジュールがSwarmで使用されることはありません。構成キャッシュの削除方法については、「Swarm構成キャッシュファイルの削除」を参照してください。
  5. 移行後のカスタムモジュールが正しく機能することを確認してから、そのモジュールを本番環境のシステムに移行します。

アクティビティイベントや電子メールなどに対する影響

変更のサブミット、ファイルの保留、ジョブの追加、ジョブの編集など、Helixサーバで何らかの操作が実行された場合や、コメントの追加やレビュー状態の変更などによってSwarm内で状態が変更された場合は、対応するイベントがSwarmのタスクキューにプッシュされます。バックグラウンドで実行されるワーカープロセスがタスクキューからイベントをプルし、処理に関係する可能性のある操作についてモジュールに警告を行うイベントを発行します。この仕組みにより、処理に時間がかかるタスクの実行中や、関連情報が使用可能な状態になるまで待機しなければならない状況においても、Swarmのユーザインタフェースの動作が極端に遅くなることはありません。

ワーカーイベントのサブスクライバーは、変更やジョブの詳細情報のフェッチなどによって項目を具体化し、その項目の結果がどうなるのか(アクティビティの入力になるのか、電子メール通知になるのかなど)を示します。カスタムモジュールは、さまざまなイベントトピックをサブスクライブすることにより、特定のタイプのイベントに注意を向けることができるようになります。イベントを処理するカスタムモジュールは、アクティビティイベントのテキストを変更したり、電子メールの内容を変更したり、アクティビティの特定の要素を完全に削除したりすることができます。

カスタムモジュールを使用してイベントをサブスクライブする場合は、そのモジュールが実行されるプロセス内での優先度(早い段階で実行するのか、遅い段階で実行するのか)を設定する必要があります。他の多くのモジュールによる処理が終了してから、Swarmのイベントモジュールが処理を開始するまでの間に、自分のモジュールを実行することができます。以下に示すイベントモジュールをサンプルとして使用して、各種のイベントをサブスクライブすることをお勧めします。

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

ヒント

このモジュールの優先度は「-100」に設定されています。必要に応じて、適切な値を設定してください。例えば、どの段階でモジュールを実行してもかまわない場合は「0」を設定し、遅い段階で実行する場合は「-90」などの値を設定します。

イベントの優先度は、「0」を中心として、最も大きい正数から、最も小さい負数までの順で処理が進められます。タスクの詳細なリストとイベントの優先度については、「タスクの詳細」を参照してください。

タスクタイプ

以下の各タスクの詳細については、「タスクの詳細」を参照してください。

  • 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

テンプレート

カスタムモジュールを使用して、既存のビューテンプレートをオーバーライドすることができます。このサンプルモジュールを使用して、コメント通知用にSwarmが使用する電子メールテンプレートをカスタマイズする方法を確認してください。

ビューの詳細については、「Laminas-View Quick Start」を参照してください。

注意

Swarmは、LICENSE.txtファイルに記載されているバージョンのLaminasコンポーネントをサポートしています。それ以降のバージョンのLaminasで導入されたLaminasドキュメントは、Swarmでは動作しません。LICENSE.txtファイルは、Swarmのインストール環境のreadmeフォルダに保管されています。

カスタムモジュールのファイルの場所

カスタムモジュールファイルは、以下に示すPSR-4標準の場所に保管する必要があります。

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

ファクトリを使用して、IndexControllersを作成することができます。IndexControllersによってApplication\Controller\AbstractIndexControllerが拡張され、SwarmIndexControllerFactoryが使用されます。そのため、IndexControllerFactoryを使用して、サービスを自動的に挿入することができます。

ヒント

文字列表記のエラーを防ぐために、::class説明を使用することをお勧めします。

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

ビューヘルパー

ファクトリを使用して、ビューヘルパーを作成することができます。ビューヘルパーを作成するためのファクトリを使用して、必要なサービスを挿入する必要があります。

ヒント

エラーの可能性を下げるために、任意の文字列ではなく、::classを使用することをお勧めします。クラスを使用することで、ファクトリがシンプルになるというメリットもあります。これは、すべてのヘルパーが共通の親クラスを継承する場合、リフレクションを使用してヘルパーを構築できるからです。

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

既存のヘルパーのオプションを設定する

既存のビューヘルパーのオプションを設定することにより、そのビューヘルパーの動作を変更することができます。設定例については、swarm_install/module/Application/Module.phpを参照してください。

新しいヘルパーを登録する

モジュールの階層内に新しいビューヘルパーを配置することにより、そのビューヘルパーを登録することができます。登録例については、MyModule/src/View/Helper/Foo.phpを参照してください。参照用として、次のSwarmビューヘルパーを使用することをお勧めします: swarm_install/module/Activity/src/View/Helper/Activity.php

次に、ModuleConfigでビューマネージャを使用して、ビューヘルパーを登録してください: swarm_root/module/Activity/config/module.config.php

イベントリスナー

イベントリスナーにより、Events\Listener\AbstractEventListenerが拡張されます。そのため、独自のファクトリを記述することなく、ListenerFactoryでリスナーを作成することができます。

Listener.phpファイルには、イベントリスナーの実装が記述されています。module.config.phpファイルには、イベントリスナーの構成が記述されています。

ヒント
  • module/events/src/Listenerディレクトリ内のAbstractEventListener.phpファイルに記述されているコードを表示して、使用可能な関数を確認してください。
  • イベントリスナーを作成して宣言型モデルを使用することを強くお勧めします。非宣言型モデルと比べた場合、宣言型モデルには以下の利点があります。
    • AbstractEventListenerは、リスナーが使用できる共通コードを提供します。
    • 宣言型モデルには、便利なデバッグオプション(ログ記録)が用意されています。
    • 宣言型モデルの場合、読みやすいコードを記述できるため、メンテナンスも簡単です。

イベントリスナー用の宣言型モデルを使用するmodule.config.phpファイルの例:

ヒント

Listener::class例の詳細は以下のとおりです。

  • Events\Listener\ListenerFactory::ALL => [
  • ここでは、便宜上ALLを待機します。待機対象の電子メールイベントは、すべてのイベントでトリガされるためです。通常は、興味のあるイベントだけを待機することをお勧めします。例えば、コミットと保留状態に興味がある場合は、COMMITイベントとSHELVEイベントを待機します。

  • Events\Listener\ListenerFactory::PRIORITY => -199,
  • イベントリスナーに対してイベント優先度-199を宣言します。これは、電子メール配信イベントが優先度-200で処理され、例のイベントは電子メール配信イベントの直前に実行する必要があるためです。

  • Events\Listener\ListenerFactory::CALLBACK => 'handleEmail',
  • 呼び出されるリスナークラス内で関数名を宣言します。

  • Events\Listener\ListenerFactory::MANAGER_CONTEXT => 'queue'
  • SwarmSwarmイベントキューを処理するときに、カスタムリスナーをトリガします。

<?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'
                ]
            ]
        ]
    ]
];		

電子メールのListener.phpファイルの例:

namespace MyModuleName\Listener;

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

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

カスタムモジュールを有効にする

Swarmcustom.modules.config.phpファイルを使用して、どのカスタムモジュールをロードするかを判断します。これにより、Swarmがどのモジュールを読み込むかを制御し、モジュールが誤って読み込まれることを防ぐことができます。

custom.modules.config.phpファイルがconfigディレクトリ(modulesディレクトリに対応するディレクトリ)内に作成されていない場合は、新しく作成してください。ファイルを編集し、各モジュールに以下の詳細情報を含めます。

  • namespaces配列には、カスタムモジュールの名前とパスを指定します。
  • return配列には、カスタムモジュールの名前を指定します。

例えば、MyModuleNameAnotherModuleNameNewModuleNameという3つのモジュールがある場合、ファイルの内容は以下のようになります。

<?php
\Laminas\Loader\AutoloaderFactory::factory(
    array(
        'Laminas\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',
];

詳細情報

Laminas Frameworkの詳細情報と例については、以下を参照してください。

  • LaminasクイックスタートドキュメンテーションLaminas Frameworkドキュメンテーションポータル: 独自のモジュールを作成する前に、Laminas Frameworkの基本的な知識を理解しておくことをお勧めします。
  • 注意

    Swarmは、LICENSE.txtファイルに記載されているバージョンのLaminasコンポーネントをサポートしています。それ以降のバージョンのLaminasで導入されたLaminasドキュメントは、Swarmでは動作しません。LICENSE.txtファイルは、Swarmのインストール環境のreadmeフォルダに保管されています。

  • Linkifyモジュールのサンプル: これは、チェンジリスト、ジョブ、コードレビューの説明、コメント、アクティビティエントリへのリンクが含まれているテキスト部分を置換するためのシンプルなカスタムモジュールです。
  • 電子メールモジュールのサンプル: これは、コメント通知の送信時にSwarmでカスタムのメールテンプレートを使用するためのシンプルなカスタムモジュールです。
  • Swarm JIRAモジュール。Swarmによるシンプルなモジュール実装です: swarm_install/module/Jira