Repository navigation
Expand file tree
/
Copy pathRemotePlusClient.php
More file actions
206 lines (173 loc) · 6.41 KB
/
Copy pathRemotePlusClient.php
File metadata and controls
206 lines (173 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php
namespace DPRMC\InteractiveData;
use DPRMC\InteractiveData\RemotePlusClient\Exceptions\UnparsableDateSentToConstructor;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
/**
* This is the parent class that all API calls must extend.
* Class RemotePlusClient
* @package DPRMC\InteractiveData
*/
abstract class RemotePlusClient {
/**
* @var string The base URI for the Remote Plus system.
*/
protected $baseUri = 'http://rplus.interactivedata.com';
/**
* @var string The page (resource) to POST your Remote Plus query.
*/
protected $page = '/cgi/nph-rplus';
/**
* @var string Your username supplied by Interactive Data.
*/
protected $user = '';
/**
* @var string The password assigned to your username from Interactive Data.
*/
protected $pass = '';
/**
* @var \GuzzleHttp\Client The GuzzleHttp client used to POST to the Remote Plus API.
*/
protected $client;
/**
* @var Request; The request to the Remote Plus API
*/
protected $request;
/**
* @var Response The response from the Remote Plus API
*/
protected $response;
/**
* @var string The value required by Remote Plus for authentication.
*/
protected $authorizationHeaderValue = '';
/**
* @var bool A parameter we pass in the request to Remote Plus to enable debugging information to be returned.
*/
protected $remotePlusDebug = TRUE;
/**
* @var float The HTTP version that Remote Plus expects for requests.
*/
protected $remotePlusHttpVersion = 1.0;
/**
* @var string The Content-Type header value that Remote Plus is expecting.
*/
protected $remotePlusContentType = 'application/x-www-form-urlencoded';
/**
* @var string The formatted body of the request being sent to the Remote Plus API.
*/
protected $requestBody = '';
/**
* RemotePlusClient constructor.
*
* @param $user string The username given to you by Interactive Data
* @param $pass string The password for the above username.
*/
public function __construct( $user, $pass ) {
$this->user = $user;
$this->pass = $pass;
$this->client = new Client( [ 'base_uri' => $this->baseUri ] );
$this->authorizationHeaderValue = $this->getAuthenticationHeaderValue( $this->user, $this->pass );
}
/**
* Returns the value required by Remote Plus for the Authorization header.
*
* @param string $username The username set by Interactive Data
* @param string $pass The password assigned by Interactive Data
*
* @return string The value needed for the Authorization header.
*/
protected function getAuthenticationHeaderValue( $username, $pass ) {
return "Basic " . $this->encodeUserAndPassForBasicAuthentication( $username, $pass );
}
/**
* Encodes the user and pass as required by the Basic Authorization.
* @see https://en.wikipedia.org/wiki/Basic_access_authentication
*
* @param string $username The username set by Interactive Data
* @param string $pass The password assigned by Interactive Data
*
* @return string The base64 encoded user:pass string.
*/
protected function encodeUserAndPassForBasicAuthentication( $username, $pass ) {
return base64_encode( $username . ':' . $pass );
}
/**
* @return mixed
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function run() {
$this->generateBodyForRequest();
$this->response = $this->sendRequest();
return $this->processResponse();
}
/**
* Sends the request to Remote Plus, and saves the Response object into our local $response property.
* @return mixed|\Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function sendRequest() {
return $this->client->request( 'POST', $this->page, [
'debug' => $this->remotePlusDebug,
'version' => $this->remotePlusHttpVersion,
'headers' => [ 'Content-Type' => $this->remotePlusContentType,
'Authorization' => $this->getAuthenticationHeaderValue( $this->user, $this->pass ), ],
'body' => $this->requestBody,
] );
}
/**
* The RemotePlus system requires dates to be formatted as yyyymmdd
* @param string $date Any string that can be parsed by PHP's strtotime()
* @return string The $date parameter formatted as yyyymmdd (or in PHP's syntax: Ymd)
* @throws UnparsableDateSentToConstructor
*/
protected function formatDateForRemotePlus( string $date ) {
$strTime = strtotime( $date );
if ( $strTime === FALSE ):
throw new UnparsableDateSentToConstructor( "We could not parse the date you sent to the constructor: [" . $date . "]" );
endif;
$date = date( 'Ymd', $strTime );
return (string)$date;
}
/**
* Extracted this into it's own function so I can stub and test without
* having to make a request to the IDC server.
* @return string
* @codeCoverageIgnore
*/
protected function getBodyFromResponse() {
return (string)$this->response->getBody();
}
/**
* @param $value
* @return float
*/
protected function formatValueReturnedFromInteractiveData( $value ) {
if ( is_numeric( $value ) ):
return (float)$value;
endif;
/**
* “!NA” not available
* “!NH” holiday (only applicable to US/Canadian securities)
* “!NE” not expected (e.g., prices for future dates)
* “!NR” not reported
* “!N5” an error code 5000 was returned
* “!N6” an error code 6000 was returned
* “!N7” an error code 7000 was returned
* “!N8” an error code 8000 was returned
*/
return NULL;
}
/**
* It's up to each child class to determine what it does with the results
* sent back from Remote Plus.
*/
abstract protected function processResponse();
/**
* Sets the $this->requestBody property. Every type of request sent to
* Remote Plus has a different syntax. It makes sense to force the child
* classes to implement that code.
*/
abstract protected function generateBodyForRequest();
}