|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
namespace P2A\YourMembership\Core; |
|
4
|
|
|
|
|
5
|
|
|
use GuzzleHttp\Psr7\Request as GuzzleRequest; |
|
6
|
|
|
|
|
7
|
|
|
|
|
8
|
|
|
class Request |
|
9
|
|
|
{ |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* Base URL |
|
13
|
|
|
* @var string |
|
14
|
|
|
*/ |
|
15
|
|
|
const BASE_URL = 'https://api.yourmembership.com'; |
|
16
|
|
|
const API_VERSION = '2.25'; |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Session ID use for YourMembership API |
|
20
|
|
|
* @var string |
|
21
|
|
|
*/ |
|
22
|
|
|
private static $sessionId = null; |
|
23
|
|
|
/** |
|
24
|
|
|
* Call Counter for Your Membership for a given session |
|
25
|
|
|
* @var integer |
|
26
|
|
|
*/ |
|
27
|
|
|
public static $callId = 0; |
|
28
|
|
|
/** |
|
29
|
|
|
* API Key Used for YourMembership API |
|
30
|
|
|
* @var string |
|
31
|
|
|
*/ |
|
32
|
|
|
private $apiKey; |
|
33
|
|
|
/** |
|
34
|
|
|
* Sa Passcode is a supplementary API key used for YourMembership API |
|
35
|
|
|
* @var string |
|
36
|
|
|
*/ |
|
37
|
|
|
private $saPasscode; |
|
38
|
|
|
|
|
39
|
|
|
|
|
40
|
4 |
|
public function __construct(string $apiKey, string $saPasscode) |
|
41
|
|
|
{ |
|
42
|
4 |
|
$this->apiKey = $apiKey; |
|
43
|
4 |
|
$this->saPasscode = $saPasscode; |
|
44
|
4 |
|
} |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* Create the Base Envelope for an API call to YourMembership |
|
48
|
|
|
* @method buildBasePayload |
|
49
|
|
|
* @author PA |
|
50
|
|
|
* @date 2017-01-09 |
|
51
|
|
|
* @return SimpleXMLElement XML Envelope with necessary credential parameters |
|
52
|
|
|
*/ |
|
53
|
3 |
|
public function buildBasePayload() : \SimpleXMLElement |
|
54
|
|
|
{ |
|
55
|
|
|
/* |
|
56
|
|
|
<YourMembership> |
|
57
|
|
|
<Version>2.25</Version> |
|
58
|
|
|
<ApiKey>3D638C5F-CCE2-4638-A2C1-355FA7BBC917</ApiKey> |
|
59
|
|
|
<CallID>001</CallID> |
|
60
|
|
|
<SaPasscode>************</SaPasscode> |
|
61
|
|
|
</YourMembership> |
|
62
|
|
|
*/ |
|
63
|
3 |
|
$xml = new \SimpleXMLElement('<YourMembership></YourMembership>'); |
|
64
|
3 |
|
$xml->addChild('Version', self::API_VERSION); |
|
65
|
3 |
|
$xml->addChild('ApiKey', $this->apiKey); |
|
66
|
3 |
|
$xml->addChild('CallID', self::$callId); |
|
67
|
3 |
|
$xml->addChild('SaPasscode', $this->saPasscode); |
|
68
|
|
|
|
|
69
|
3 |
|
return $xml; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
/** |
|
73
|
|
|
* Generates the XML for a API method call within |
|
74
|
|
|
* @method createCallPayload |
|
75
|
|
|
* @author PA |
|
76
|
|
|
* @date 2017-01-09 |
|
77
|
|
|
* @param string $method YourMembership API Function Name |
|
78
|
|
|
* @param array $arguments Array of Arguments to be passed as part of the YourMembership "Call" |
|
79
|
|
|
* @return \SimpleXMLElement |
|
80
|
|
|
*/ |
|
81
|
3 |
|
public function createCallPayload(string $method, array $arguments) : \SimpleXMLElement |
|
82
|
|
|
{ |
|
83
|
|
|
//Create Call Node |
|
84
|
3 |
|
$call = new \SimpleXMLElement('<Call> </Call>'); |
|
85
|
3 |
|
$call->addAttribute('Method',$method); |
|
86
|
|
|
|
|
87
|
|
|
//Add Arguments to the Call Node |
|
88
|
3 |
|
foreach ($arguments as $key => $value) { |
|
89
|
3 |
|
$call->addChild($key,$value); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
3 |
|
return $call; |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* Builds The XML Request Body for the Your Membership API Call |
|
97
|
|
|
* @method buildXMLBody |
|
98
|
|
|
* @author PA |
|
99
|
|
|
* @date 2017-01-10 |
|
100
|
|
|
* @param string $method Your Membership API Function Name |
|
101
|
|
|
* @param array $arguments Your Membership Arguments |
|
102
|
|
|
* @return SimpleXMLElement |
|
103
|
|
|
*/ |
|
104
|
2 |
|
public function buildXMLBody(string $method, array $arguments) : \SimpleXMLElement |
|
105
|
|
|
{ |
|
106
|
2 |
|
$xml = $this->buildBasePayload(); // Common Envelope |
|
107
|
|
|
|
|
108
|
2 |
|
if ($this->isSessionRequiredForMethod($method)) { |
|
109
|
2 |
|
$xml = $this->addSessionIdToRequest($xml); |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
2 |
|
$callPayload = $this->createCallPayload($method, $arguments); // Specific API Call Envelope |
|
113
|
|
|
|
|
114
|
|
|
// Put Api call into common envelope |
|
115
|
2 |
|
$this->sxmlAppend($xml,$callPayload); |
|
116
|
|
|
|
|
117
|
2 |
|
return $xml; |
|
118
|
|
|
} |
|
119
|
|
|
/** |
|
120
|
|
|
* Builds a Guzzle Request Object |
|
121
|
|
|
* @method buildRequest |
|
122
|
|
|
* @author PA |
|
123
|
|
|
* @date 2017-01-11 |
|
124
|
|
|
* @param string $method YourMembership API Method |
|
125
|
|
|
* @param array $arguments YourMembership API Method Call Arguments |
|
126
|
|
|
* @return \GuzzleHttp\Psr7\Request Guzzle Request Object |
|
127
|
|
|
*/ |
|
128
|
1 |
|
public function buildRequest(string $method, array $arguments) : \GuzzleHttp\Psr7\Request |
|
129
|
|
|
{ |
|
130
|
1 |
|
$requestBody = $this->buildXMLBody($method, $arguments)->asXML(); |
|
131
|
1 |
|
return new GuzzleRequest('POST', self::BASE_URL, ['Content-Type' => 'application/x-www-form-urlencoded; charset=UTF8'], $requestBody); |
|
|
|
|
|
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* Checks if Request Requires Session ID |
|
136
|
|
|
* @method isSessionRequiredForMethod |
|
137
|
|
|
* @author PA |
|
138
|
|
|
* @date 2017-01-10 |
|
139
|
|
|
* @param string $method YourMembership API Method |
|
140
|
|
|
* @return bool |
|
141
|
|
|
*/ |
|
142
|
2 |
|
public function isSessionRequiredForMethod(string $method) : bool |
|
143
|
|
|
{ |
|
144
|
|
|
//TODO Add config Logic for what API Methods require Session ID |
|
145
|
2 |
|
return ($method != 'Session.Create'); |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* Helper for Deep Copy for of $from element into $to element for SimpleXML |
|
150
|
|
|
* @method sxmlAppend |
|
151
|
|
|
* @author PA |
|
152
|
|
|
* @date 2017-01-09 |
|
153
|
|
|
* @param SimpleXMLElement $to |
|
154
|
|
|
* @param SimpleXMLElement $from |
|
155
|
|
|
* @return void |
|
156
|
|
|
*/ |
|
157
|
2 |
|
private function sxmlAppend(\SimpleXMLElement $to, \SimpleXMLElement $from) { |
|
158
|
2 |
|
$toDom = dom_import_simplexml($to); |
|
159
|
2 |
|
$fromDom = dom_import_simplexml($from); |
|
160
|
2 |
|
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true)); |
|
161
|
2 |
|
} |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
* Adds the Session Variable to the given XML Request Payload |
|
165
|
|
|
* @method addSessionIdToRequest |
|
166
|
|
|
* @author PA |
|
167
|
|
|
* @date 2017-01-10 |
|
168
|
|
|
* @param \SimpleXMLElement $requestXML Base Request XML Payload |
|
169
|
|
|
*/ |
|
170
|
2 |
|
private function addSessionIdToRequest(\SimpleXMLElement $requestXML) : \SimpleXMLElement |
|
171
|
|
|
{ |
|
172
|
2 |
|
$requestXML->addChild('SessionID', self::$sessionId); |
|
173
|
2 |
|
return $requestXML; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Setter Method for SessionID |
|
179
|
|
|
* @method setSessionId |
|
180
|
|
|
* @author PA |
|
181
|
|
|
* @date 2017-01-10 |
|
182
|
|
|
* @param string $sessionId YourMembership Session ID |
|
183
|
|
|
*/ |
|
184
|
1 |
|
public static function setSessionId(string $sessionId) |
|
185
|
|
|
{ |
|
186
|
1 |
|
self::$sessionId = $sessionId; |
|
187
|
1 |
|
} |
|
188
|
|
|
|
|
189
|
|
|
/** |
|
190
|
|
|
* Checks if we have an active session available |
|
191
|
|
|
* @method hasSession |
|
192
|
|
|
* @author PA |
|
193
|
|
|
* @date 2017-01-11 |
|
194
|
|
|
* @return boolean |
|
195
|
|
|
*/ |
|
196
|
1 |
|
public function hasSession() { |
|
197
|
1 |
|
return !is_null(self::$sessionId); |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
}; |
|
201
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.