Completed
Push — master ( 0de3ab...a09f81 )
by Drew
01:54
created

Webhook   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 13
c 1
b 0
f 1
lcom 1
cbo 0
dl 0
loc 77
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A subscribe() 0 7 2
A receive() 0 16 4
A processWebhook() 0 13 4
A dispatchWebhookEvent() 0 10 3
1
<?php
2
3
namespace DrewM\MailChimp;
4
5
/**
6
 * A MailChimp Webhook request.
7
 * How to Set Up Webhooks: http://eepurl.com/bs-j_T
8
 *
9
 * @author Drew McLellan <[email protected]>
10
 */
11
class Webhook
12
{
13
	private static $eventSubscriptions = [];
14
	private static $receivedWebhook = false;
15
16
	/**
17
	 * Subscribe to an incoming webhook request. The callback will be invoked when a matching webhook is received.
18
	 * @param string $event Name of the webhook event, e.g. subscribe, unsubscribe, campaign
19
	 * @param callable $callback A callable function to invoke with the data from the received webhook
20
     * @return void
21
	 */
22
	public static function subscribe($event, callable $callback)
23
	{
24
		if (!isset(self::$eventSubscriptions[$event])) self::$eventSubscriptions[$event] = [];
25
		self::$eventSubscriptions[$event][] = $callback;
26
27
		self::receive();
28
	}
29
30
	/**
31
	 * Retrieve the incoming webhook request as sent.
32
	 * @param string $input An optional raw POST body to use instead of php://input - mainly for unit testing.
33
     * @return array|false 	An associative array containing the details of the received webhook
34
	 */
35
	public static function receive($input = null)
36
	{
37
		if (is_null($input)) {
38
			if (self::$receivedWebhook !== false) {
39
				$input = self::$receivedWebhook;
40
			} else {
41
				$input = file_get_contents("php://input");
42
			}
43
		}
44
45
		if ($input) {
46
			return self::processWebhook($input);
0 ignored issues
show
Bug introduced by
It seems like $input can also be of type boolean; however, DrewM\MailChimp\Webhook::processWebhook() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
47
		}	
48
		
49
		return false;
50
	}
51
52
	/**
53
	 * Process the raw request into a PHP array and dispatch any matching subscription callbacks
54
	 * @param string $input The raw HTTP POST request
55
	 * @return array|false 	An associative array containing the details of the received webhook
56
	 */
57
	private static function processWebhook($input) 
58
	{
59
		if ($input) {
60
			self::$receivedWebhook = $input;
0 ignored issues
show
Documentation Bug introduced by
The property $receivedWebhook was declared of type boolean, but $input is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
61
			parse_str($input, $result);
62
			if ($result && isset($result['type'])) {
63
				self::dispatchWebhookEvent($result['type'], $result['data']);
64
				return $result;
65
			}
66
		}
67
68
		return false;
69
	}
70
71
	/**
72
	 * Call any subscribed callbacks for this event
73
	 * @param string $event The name of the callback event
74
	 * @param array $data An associative array of the webhook data
75
	 * @return void
76
	 */
77
	private static function dispatchWebhookEvent($event, $data)
78
	{
79
		if (isset(self::$eventSubscriptions[$event])) {
80
			foreach(self::$eventSubscriptions[$event] as $callback) {
81
				$callback($data);
82
			}
83
			// reset subscriptions
84
			self::$eventSubscriptions[$event] = [];
85
		}
86
	}
87
}