Test Setup Failed
Push — 0.1-dev ( 06ac17...3ceb1a )
by Petr
02:03
created

Request::createCallPayload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
3
namespace P2A\YourMembership\Core;
4
5
use GuzzleHttp\Psr7\Request as GuzzleRequest;
6
use P2A\YourMembership\Exceptions\YourMembershipException;
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
    public function __construct(string $apiKey, string $saPasscode)
41
    {
42
        $this->apiKey = $apiKey;
43
        $this->saPasscode = $saPasscode;
44
    }
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
    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
        $xml = new \SimpleXMLElement('<YourMembership></YourMembership>');
64
        $xml->addChild('Version', self::API_VERSION);
65
        $xml->addChild('ApiKey', $this->apiKey);
66
        $xml->addChild('CallID', self::$callId);
67
        $xml->addChild('SaPasscode', $this->saPasscode);
68
69
        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
    public function createCallPayload(string $method, array $arguments) : \SimpleXMLElement
82
    {
83
        //Create Call Node
84
        $call = new \SimpleXMLElement('<Call> </Call>');
85
        $call->addAttribute('Method', $method);
86
87
        //Add Arguments to the Call Node
88
89
        $call = $this->sxmlAddChildrenRecursive($call,$arguments);
90
91
        return $call;
92
    }
93
    /**
94
     * Recursively builds the array into a XML Tree
95
     * //NOTE Child arrays must be associative
96
     * @method sxmlAddChildrenRecursive
97
     * @author PA
98
     * @date   2017-01-12
99
     * @param  SimpleXMLElement         $root      Root XML Node
100
     * @param  array                    $arguments Array of Arguments to be added to XML Node
101
     * @return SimpleXMLElement                    Resulting XML Tree
102
     */
103
    private function sxmlAddChildrenRecursive(\SimpleXMLElement $root, array $arguments) : \SimpleXMLElement
104
    {
105
        foreach ($arguments as $key => $value) {
106
            if (is_array($value)) {
107
                try {
108
                    $child = new \SimpleXMLElement(sprintf('<%s></%s>',$key, $key));
109
                    $this->sxmlAddChildrenRecursive($child, $value);
110
                    $this->sxmlAppend($root,$child);
111
                } catch(\Exception $e) {
112
                    throw new YourMembershipException($e->getMessage(), $e->getCode(), $e);
113
                }
114
            } else {
115
                $root->addChild($key, $value);
116
            }
117
118
        }
119
        return $root;
120
    }
121
    /**
122
     * Builds The XML Request Body for the Your Membership API Call
123
     * @method buildXMLBody
124
     * @author PA
125
     * @date   2017-01-10
126
     * @param  string            $method    Your Membership API Function Name
127
     * @param  array             $arguments Your Membership Arguments
128
     * @return \SimpleXMLElement
129
     */
130
    public function buildXMLBody(string $method, array $arguments) : \SimpleXMLElement
131
    {
132
        $xml = $this->buildBasePayload(); // Common Envelope
133
134
        if ($this->isSessionRequiredForMethod($method)) {
135
            $xml = $this->addSessionIdToRequest($xml);
136
        }
137
138
        $callPayload = $this->createCallPayload($method, $arguments); // Specific API Call Envelope
139
140
        // Put Api call into common envelope
141
        $this->sxmlAppend($xml, $callPayload);
142
143
        return $xml;
144
    }
145
    /**
146
     * Builds a Guzzle Request Object
147
     * @method buildRequest
148
     * @author PA
149
     * @date   2017-01-11
150
     * @param  string        $method    YourMembership API Method
151
     * @param  array         $arguments YourMembership API Method Call Arguments
152
     * @return \GuzzleHttp\Psr7\Request            Guzzle Request Object
153
     */
154
    public function buildRequest(string $method, array $arguments) : \GuzzleHttp\Psr7\Request
155
    {
156
        $requestBody = $this->buildXMLBody($method, $arguments)->asXML();
157
        return new GuzzleRequest('POST', self::BASE_URL, ['Content-Type' => 'application/x-www-form-urlencoded; charset=UTF8'], $requestBody);
158
    }
159
160
    /**
161
     * Checks if Request Requires Session ID
162
     * @method isSessionRequiredForMethod
163
     * @author PA
164
     * @date   2017-01-10
165
     * @param  string                     $method YourMembership API Method
166
     * @return bool
167
     */
168
    public function isSessionRequiredForMethod(string $method) : bool
169
    {
170
        //TODO Add config Logic for what API Methods require Session ID
171
        return ($method != 'Session.Create');
172
    }
173
174
    /**
175
     * Helper for Deep Copy for of $from element into $to element for SimpleXML
176
     * @method sxmlAppend
177
     * @author PA
178
     * @date   2017-01-09
179
     * @param  \SimpleXMLElement $to
180
     * @param  \SimpleXMLElement $from
181
     * @return void
182
     */
183
    private function sxmlAppend(\SimpleXMLElement $to, \SimpleXMLElement $from) {
184
        $toDom = dom_import_simplexml($to);
185
        $fromDom = dom_import_simplexml($from);
186
        $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
187
    }
188
189
    /**
190
     * Adds the Session Variable to the given XML Request Payload
191
     * @method addSessionIdToRequest
192
     * @author PA
193
     * @date   2017-01-10
194
     * @param  \SimpleXMLElement                $requestXML Base Request XML Payload
195
     */
196
    private function addSessionIdToRequest(\SimpleXMLElement $requestXML) : \SimpleXMLElement
197
    {
198
        $requestXML->addChild('SessionID', self::$sessionId);
199
        return $requestXML;
200
    }
201
202
203
    /**
204
     * Setter Method for SessionID
205
     * @method setSessionId
206
     * @author PA
207
     * @date   2017-01-10
208
     * @param  string       $sessionId YourMembership Session ID
209
     */
210
    public static function setSessionId(string $sessionId)
211
    {
212
        self::$sessionId = $sessionId;
213
    }
214
215
    /**
216
     * Checks if we have an active session available
217
     * @method hasSession
218
     * @author PA
219
     * @date   2017-01-11
220
     * @return boolean
221
     */
222
    public function hasSession()
223
    {
224
        return !is_null(self::$sessionId);
225
    }
226
227
}
228