電子メールモジュールのサンプル

以下のサンプルモジュールでは、コメント通知の送信時にSwarmが使用する電子メールテンプレートをカスタマイズする方法について説明します。

注意

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

ヒント

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

ヒント

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

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ファイルを作成するには、次の操作を実行します。

  1. モジュールディレクトリに、EmailExampleというディレクトリを作成します。
  2. module/EmailExampleModule.phpというファイルを作成します。

  3. Module.phpを編集して以下を含めます。
  4. <?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';
        }
    }
  5. 次に、module.config.phpファイルを作成するします。

module.config.phpファイルを作成する

  • module.config.phpファイルは次のことを行います。
    • イベントリスナーを含むモジュールの設定を行う。
    • イベントリスナーに対してイベント優先度-199を宣言します。これは、電子メール配信イベントが優先度-200で処理され、例のイベントは電子メール配信イベントの直前に実行する必要があるためです。
    ヒント

    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イベントキューを処理するときに、カスタムリスナーをトリガします。

    module.config.phpファイルを作成するには、次の操作を実行します。

    1. EmailExampleディレクトリに、configというディレクトリを作成します。
    2. configに、module.config.phpというファイルを作成します。
    3. module.config.phpを編集して以下を含めます。
    4. <?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'
                      ]
                  ]
              ]
          ]
      ];		
    5. 次に、Listener.phpファイルを作成するします。

    Listener.phpファイルを作成する

    Listener.phpファイルは次のことを行います。

    • イベントリスナーの実装を含む
    • ログ記録を許可する

    Listener.phpファイルを作成するには、次の操作を実行します。

    1. EmailExampleディレクトリに、srcというディレクトリを作成します。
    2. srcディレクトリに、Listenerというディレクトリを作成します。
    3. Listenerに、Listener.phpというファイルを作成します。
    4. Listener.phpを編集して以下を含めます。
    5. <?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.");
          }
      }

    6. 次に、comment-html.phtmlファイルを作成するします。

    comment-html.phtmlファイルを作成する

    comment-html.phtmlファイルは、電子メールのコメント通知のHTML部分となるビュースクリプトです。

    ヒント

    電子メールのスタイル設定にインラインCSSを使用する場合のベストプラクティスとされています。

    comment-html.phtmlファイルを作成するには、次の操作を実行します。

    1. module/Exampleディレクトリに、viewというディレクトリを作成します。
    2. module/Example/viewディレクトリに、mailというディレクトリを作成します。
    3. module/Example/view/mailcomment-html.phtmlファイルを作成します。
    4. comment-html.phtmlを編集して以下を含めます。
    5. <?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>&nbsp;'
      . $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>
    6. 次に、comment-text.phtmlファイルを作成するします。

    comment-text.phtmlファイルを作成する

    comment-text.phtmlは、電子メールのコメント通知のテキスト専用の部分となるビュースクリプトです。

    comment-text.phtmlファイルを作成するには、次の操作を実行します。

    1. module/Example/view/mailディレクトリにcomment-text.phtmlファイルを作成します。
    2. 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')); ?>
    3. 次に、custom.modules.config.phpでSwarmに対してEmailExampleモジュールを有効にするにします。

    custom.modules.config.phpでSwarmに対してEmailExampleモジュールを有効にする

    Swarmcustom.modules.config.phpファイルを使用してクラスを自動的に読み込み、実行するカスタムモジュールを確認します。これにより、Swarmがどのモジュールを読み込むかを制御し、モジュールが誤って読み込まれることを防ぐことができます。

    custom.modules.config.phpファイルを作成するには、次の操作を実行します。

    1. moduleディレクトリと同じレベルにconfigディレクトリが存在しない場合は、新しく作成します。
    2. configディレクトリにcustom.modules.config.phpファイルが存在しない場合は、新しく作成します。
    3. custom.modules.config.phpファイルを編集して、自動ローダとEmailExampleモジュールの詳細を含めます。
    4. ヒント

      すでにSwarmで1つ以上のカスタムモジュールが有効になっている場合、自動ローダと既存のモジュール詳細はファイルに含まれています。

      namespacesEmailExampleを追加し、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'
      ];
      

    5. Swarmが新しいモジュールを認識できるように、Swarmの構成キャッシュをもう一度ロードする必要があります。adminユーザまたはsuperユーザとして[ユーザID]ドロップダウンメニューにアクセスし、[システム情報]を選択して[キャッシュ情報]タブをクリックしてから、[構成の再ロード]ボタンボタンをクリックします。
    6. これで、Swarmに対してEmailExampleモジュールが有効になりました。コメントに関する通知が送信されるたびに、Swarmで新しいカスタムメールテンプレートが使用されるようになります。

    7. 実稼働サーバに移行する前に、モジュールが正常に機能することを確認してください。

    EmailExampleモジュールを他の電子メールテンプレートに拡張する

    別のタイプのSwarm電子メール通知をカスタマイズする場合は、HTMLとテキスト両方のビュースクリプトを探し、現在のファイル名のままそれらのスクリプトをmodule/Example/view/mailにコピーして、コピーしたスクリプトファイルを編集します。

    注意

    HTMLとテキストテンプレートの両方をコピーしないと、カスタマイズ済みテンプレートの検索でカスタマイズされていないバージョンのみが見つかり、モジュールが機能していないように見えるおそれがあります。