GitHubHookProcessor.php 2.41 KB
Newer Older
Michael McAndrew's avatar
Michael McAndrew committed
1 2 3 4
<?php

namespace AppBundle\Utils;

Sean Madsen's avatar
Sean Madsen committed
5
class GitHubHookProcessor {
6

7 8 9 10 11 12 13 14 15 16 17
  /**
   * @var string the URL for the repository
   */
  public $repo;

  /**
   * @var string the name of the branch to publish
   */
  public $branch;

  /**
Sean Madsen's avatar
Sean Madsen committed
18 19 20 21
   * Process a GitHub webhook
   *
   * @param string $event
   *   e.g. 'pull_request', 'push'
22
   *
Sean Madsen's avatar
Sean Madsen committed
23 24 25
   * @param mixed $payload
   *   An object given by json_decode()
   *
26 27
   * @return array
   *
Sean Madsen's avatar
Sean Madsen committed
28
   * @throws \Exception
29
   */
Sean Madsen's avatar
Sean Madsen committed
30
  public function process($event, $payload) {
Sean Madsen's avatar
Sean Madsen committed
31 32 33 34 35 36 37
    if (empty($payload)) {
      throw new \Exception("No payload data supplied");
    }
    if (empty($event)) {
      throw new \Exception("Unable to determine webhook event type from "
          . "request headers");
    }
38 39
    if ($event != 'push') {
      throw new \Exception("Webhook event type is not 'push'");
Michael McAndrew's avatar
Michael McAndrew committed
40
    }
41 42

    return $this->getDetailsFromPush($payload);
Sean Madsen's avatar
Sean Madsen committed
43 44
  }

45
  /**
46
   * Use a "push" event to figure out what branch and repo we are talking
47 48
   * about, and the also work out what emails we should send.
   *
Sean Madsen's avatar
Sean Madsen committed
49 50 51
   * @param mixed $payload
   *   An object given by json_decode()
   *
52 53
   * @return array
   *
Sean Madsen's avatar
Sean Madsen committed
54
   * @throws \Exception
55
   */
56
  protected function getDetailsFromPush($payload) {
57
    $this->branch = preg_replace("#.*/(.*)#", "$1", $payload->ref);
58 59 60
    if (empty($this->branch)) {
      throw new \Exception("Unable to determine branch from payload data");
    }
Sean Madsen's avatar
Sean Madsen committed
61
    $this->repo = $payload->repository->html_url;
62 63 64
    if (empty($this->repo)) {
      throw new \Exception("Unable to determine repository from payload data");
    }
65 66

    $recipients = [];
Sean Madsen's avatar
Sean Madsen committed
67
    foreach ($payload->commits as $commit) {
68 69
      $this->addRecipients($recipients, $commit->author->email);
      $this->addRecipients($recipients, $commit->committer->email);
Michael McAndrew's avatar
Michael McAndrew committed
70
    }
71

72 73 74 75
    return [
      'commits' => $payload->commits,
      'recipients' => $recipients
    ];
Sean Madsen's avatar
Sean Madsen committed
76 77
  }

78 79 80 81
  /**
   * Adds one or more email recipients, and makes sure all recipients are
   * kept unique
   *
82
   * @param array $new
Sean Madsen's avatar
Sean Madsen committed
83
   *   Array of strings for emails of people to notify
84 85 86 87
   * @param array $existing
   *   Existing recipients so far
   * @return array
   *   Unique array of recipients
88
   */
89 90 91
  protected function addRecipients($existing, $new) {
    if (!is_array($new)) {
      $new = array($new);
92
    }
Sean Madsen's avatar
Sean Madsen committed
93
    // remove any email addresses begins with "donotreply@" or "noreply"
94
    $new = preg_grep('/^(donot|no)reply@/', $new, PREG_GREP_INVERT);
95

96
    return array_unique(array_merge($existing, $new));
Sean Madsen's avatar
Sean Madsen committed
97
  }
Michael McAndrew's avatar
Michael McAndrew committed
98
}