電子メールモジュールのサンプル
以下のサンプルモジュールでは、コメント通知の送信時にSwarmが使用する電子メールテンプレートをカスタマイズする方法について説明します。
Swarmは、LICENSE.txtファイルに記載されているバージョンのLaminasコンポーネントをサポートしています。それ以降のバージョンのLaminasで導入されたLaminasドキュメントは、Swarmでは動作しません。LICENSE.txtファイルは、Swarmのインストール環境のreadmeフォルダに保管されています。
実稼働システムに移行する前に、必ずテストシステム上でカスタムモジュールのテストを行ってください。これにより、実稼働システムの運用に悪影響が及ぶことを防ぐことができます。複数のカスタムモジュールがある場合、すべてのモジュールを同時に同じテストシステム上でテストしてください。これにより、お互いに、そしてHelix Swarmと連携して、正しく運用できることを確認できます。
モジュールの追加や編集を行った場合、構成キャッシュを再ロードするまで、そのモジュールがSwarmで使用されることはありません。構成キャッシュを再ロードすると、そのモジュールがSwarmで強制的に使用されます。Swarm構成キャッシュを再ロードするには、admin ユーザまたはsuper ユーザでなくてはなりません。[ユーザID]ドロップダウンメニューに移動して[システム情報]を選択し、[キャッシュ情報]タブをクリックしてから[構成の再ロード]ボタンボタンをクリックします。
EmailExampleモジュールを作成するために必要な基本手順は以下のとおりです。
- Module.phpファイルを作成する
- module.config.phpファイルを作成する
- Listener.phpファイルを作成する
- comment-html.phtmlファイルを作成する
- comment-text.phtmlファイルを作成する
- custom.modules.config.phpでSwarmに対してEmailExampleモジュールを有効にする
詳細情報:
EmailExampleモジュールを他の電子メールテンプレートに拡張する
ファイルの場所
ご参考までに、EmailExampleモジュールは以下のファイル名とファイルの場所を使用します。
config/ custom.modules.config.php module/ EmailExample/ config/ module.config.php src/ Listener/ Listener.php view/ mail/ commit-html.phtml commit-text.phtml comment-html.phtml comment-text.phtml review-html.phtml review-text.phtml Module.php
Module.phpファイルを作成する
Module.phpは次のことを行います:
- モジュールのディレクトリ名に一致する、モジュールのネームスペースを宣言します。
- getConfig()関数を提供します。
任意指定: モジュールを読み込む際に何らかの初期設定を行う場合は、onBootstrap (Event $event)関数を実装することもできます。
public function onBootstrap(Event $event)
{
}
EventはLaminasクラスで、ネームスペースの後に追加されます。
namespace EmailExample
use Laminas\EventManager\Event
Module.phpファイルを作成するには、次の操作を実行します。
- モジュールディレクトリに、EmailExampleというディレクトリを作成します。
-
module/EmailExampleにModule.phpというファイルを作成します。
- Module.phpを編集して以下を含めます。
- 次に、module.config.phpファイルを作成するします。
<?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>
*/
namespace EmailExample;
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
module.config.phpファイルを作成する
- イベントリスナーを含むモジュールの設定を行う。
- イベントリスナーに対してイベント優先度-199を宣言します。これは、電子メール配信イベントが優先度-200で処理され、例のイベントは電子メール配信イベントの直前に実行する必要があるためです。
Listener::class例の詳細は以下のとおりです。
- Events\Listener\ListenerFactory::ALL => [
- Events\Listener\ListenerFactory::PRIORITY => -199,
- Events\Listener\ListenerFactory::CALLBACK => 'handleEmail',
- Events\Listener\ListenerFactory::MANAGER_CONTEXT => 'queue'
ここでは、便宜上ALLを待機します。待機対象の電子メールイベントは、すべてのイベントでトリガされるためです。通常は、興味のあるイベントだけを待機することをお勧めします。例えば、コミットと保留状態に興味がある場合は、COMMITイベントとSHELVEイベントを待機します。
イベントリスナーに対してイベント優先度-199を宣言します。これは、電子メール配信イベントが優先度-200で処理され、例のイベントは電子メール配信イベントの直前に実行する必要があるためです。
呼び出されるリスナークラス内で関数名を宣言します。
SwarmがSwarmイベントキューを処理するときに、カスタムリスナーをトリガします。
module.config.phpファイルを作成するには、次の操作を実行します。
- EmailExampleディレクトリに、configというディレクトリを作成します。
- configに、module.config.phpというファイルを作成します。
- module.config.phpを編集して以下を含めます。
- 次に、Listener.phpファイルを作成するします。
<?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ファイルを作成する
Listener.phpファイルは次のことを行います。
- イベントリスナーの実装を含む
- ログ記録を許可する
Listener.phpファイルを作成するには、次の操作を実行します。
- EmailExampleディレクトリに、srcというディレクトリを作成します。
- srcディレクトリに、Listenerというディレクトリを作成します。
- Listenerに、Listener.phpというファイルを作成します。
- Listener.phpを編集して以下を含めます。
- 次に、comment-html.phtmlファイルを作成するします。
<?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>
*/
namespace EmailExample\Listener;
use Events\Listener\AbstractEventListener;
use Laminas\EventManager\Event;
class Listener extends AbstractEventListener
{
/**
* Automatically uses any custom email templates found under this
* module's view/mail folder (e.g. Example/view/mail/commit-html.phtml).
*
* Valid templates include:
*
* commit-html.phtml (HTML version of commit notification)
* commit-text.phtml (text version of commit notification)
* comment-html.phtml (HTML version of comment notification)
* comment-text.phtml (text version of comment notification)
* review-html.phtml (HTML version of review notification)
* review-text.phtml (text version of review notification)
*
* Note: you need to provide custom templates for both HTML and text;
* if you do not provide both, it is possible that the search for
* customized templates only finds the non-customized versions, making
* it appear that this module is not working.
*/
/**
* Handle the Email and set the new templates.
*
* @param Event $event
*/
public function handleEmail(Event $event)
{
$logger = $this->services->get('logger');
$logger->info("EmailExample: handleEmail");
$mail = $event->getParam('mail');
if (!$mail || !isset($mail['htmlTemplate'], $mail['textTemplate'])) {
return;
}
$html = __DIR__ . '/view/mail/' . basename($mail['htmlTemplate']);
$text = __DIR__ . '/view/mail/' . basename($mail['textTemplate']);
if (file_exists($html)) {
$mail['htmlTemplate'] = $html;
}
if (file_exists($text)) {
$mail['textTemplate'] = $text;
}
$event->setParam('mail', $mail);
$logger->info("EmailExample: handleEmail end.");
}
}
comment-html.phtmlファイルを作成する
comment-html.phtmlファイルは、電子メールのコメント通知のHTML部分となるビュースクリプトです。
電子メールのスタイル設定にインラインCSSを使用する場合のベストプラクティスとされています。
comment-html.phtmlファイルを作成するには、次の操作を実行します。
- module/Exampleディレクトリに、viewというディレクトリを作成します。
- module/Example/viewディレクトリに、mailというディレクトリを作成します。
- module/Example/view/mailにcomment-html.phtmlファイルを作成します。
- comment-html.phtmlを編集して以下を含めます。
- 次に、comment-text.phtmlファイルを作成するします。
<?php
$user = $activity->get('user');
$userLink = $user
? $this->qualifiedUrl('user', array('user' => $user))
: null;
$targetLink = $activity->getUrl($this->plugin('qualifiedUrl'));
?>
<html>
<body style="font-family: sans-serif; background-color: #eee; padding: 1em;">
<div style="background-color: #fff; border: 1px solid #ccc; padding: 1em;">
<div style="font-size: 115%;">
<?php if ($user): ?>
<a style="text-decoration: none;" href="<?php echo $userLink ?>">
<?php echo $this->escapeHtml($user) ?>
</a>
<?php endif; ?>
<?php echo $this->escapeHtml($activity->get('action')) ?>
<a style="text-decoration: none;" href="<?php echo $targetLink ?>">
<?php echo $this->escapeHtml($activity->get('target'))?>
</a>
</div>
<br/>
<?php
// if the comment has file context, show it.
$comment = $event->getParam('comment');
$context = $comment
? $comment->getFileContext()
: array('content' => null, 'line' => null);
if (is_array($context['content']) && $context['line']) {
$line = $context['line'] - count($context['content']) + 1;
echo '<div style="font-family: monospace; white-space: nowrap;'
. ' padding: .5em 1em; overflow-x: auto; color: #444;'
. ' border: 1px solid #ddd; background-color: #f7f7f7;">';
foreach ((array) $context['content'] as $i => $content) {
echo '<div><span style="color: #999;">'
. str_pad($line + $i,
strlen($context['line']),
"0",
STR_PAD_LEFT
)
. '.</span> '
. $this->preformat($content)
->setLinkify(false)
->setEmojify(false)
->setWordWrap(900)
. "</div>\n";
}
echo '</div><br/>';
}
?>
<div style="padding-bottom: .5em;">
<?php
echo $this->preformat($activity->get('description'))
->setBaseUrl($this->qualifiedUrl())
->setEmojify(false)
->setWordWrap(900)
?>
</div>
</div>
</body>
</html>
comment-text.phtmlファイルを作成する
comment-text.phtmlは、電子メールのコメント通知のテキスト専用の部分となるビュースクリプトです。
comment-text.phtmlファイルを作成するには、次の操作を実行します。
- module/Example/view/mailディレクトリにcomment-text.phtmlファイルを作成します。
- comment-text.phtmlを編集して以下を含めます。
<?php
echo trim($activity->get('user')
. ' commented on '
. $activity->get('target'));
// if the comment has file context, show it.
$comment = $event->getParam('comment');
$context = $comment
? $comment->getFileContext()
: array('content' => null);
if (is_array($context['content'])) {
echo "\n\n> " . $this->wordWrap(
implode("\n> ", $context['content']), 900
);
} echo "\n\n" . trim($this->wordWrap($activity->get('description'), 900)); echo "\n\n" . $activity->getUrl($this->plugin('qualifiedUrl')); ?> - 次に、custom.modules.config.phpでSwarmに対してEmailExampleモジュールを有効にするにします。
custom.modules.config.phpでSwarmに対してEmailExampleモジュールを有効にする
Swarmはcustom.modules.config.phpファイルを使用してクラスを自動的に読み込み、実行するカスタムモジュールを確認します。これにより、Swarmがどのモジュールを読み込むかを制御し、モジュールが誤って読み込まれることを防ぐことができます。
custom.modules.config.phpファイルを作成するには、次の操作を実行します。
- moduleディレクトリと同じレベルにconfigディレクトリが存在しない場合は、新しく作成します。
- configディレクトリにcustom.modules.config.phpファイルが存在しない場合は、新しく作成します。
- custom.modules.config.phpファイルを編集して、自動ローダとEmailExampleモジュールの詳細を含めます。
- Swarmが新しいモジュールを認識できるように、Swarmの構成キャッシュをもう一度ロードする必要があります。adminユーザまたはsuperユーザとして[ユーザID]ドロップダウンメニューにアクセスし、[システム情報]を選択して[キャッシュ情報]タブをクリックしてから、[構成の再ロード]ボタンボタンをクリックします。
- 実稼働サーバに移行する前に、モジュールが正常に機能することを確認してください。
すでにSwarmで1つ以上のカスタムモジュールが有効になっている場合、自動ローダと既存のモジュール詳細はファイルに含まれています。
namespacesにEmailExampleを追加し、custom.modules.config.phpファイルのreturn配列を追加します。
<?php
\Laminas\Loader\AutoloaderFactory::factory(
array(
'Laminas\Loader\StandardAutoloader' => array(
'namespaces' => array(
'EmailExample' => BASE_PATH . '/module/EmailExample/src',
)
)
)
);
return [
'EmailExample'
];
これで、Swarmに対してEmailExampleモジュールが有効になりました。コメントに関する通知が送信されるたびに、Swarmで新しいカスタムメールテンプレートが使用されるようになります。
EmailExampleモジュールを他の電子メールテンプレートに拡張する
別のタイプのSwarm電子メール通知をカスタマイズする場合は、HTMLとテキスト両方のビュースクリプトを探し、現在のファイル名のままそれらのスクリプトをmodule/Example/view/mailにコピーして、コピーしたスクリプトファイルを編集します。
HTMLとテキストテンプレートの両方をコピーしないと、カスタマイズ済みテンプレートの検索でカスタマイズされていないバージョンのみが見つかり、モジュールが機能していないように見えるおそれがあります。