Netsutie PHP Toolkit
NSPHPClient.php
Go to the documentation of this file.
1 <?php
2 
3 require "NSconfig.php";
4 
5 function arrayValuesAreEmpty ($array)
6 {
7  if (!is_array($array))
8  {
9  return false;
10  }
11 
12  foreach ($array as $key => $value)
13  {
14  if ( $value === false || ( !is_null($value) && $value != "" && !arrayValuesAreEmpty($value)))
15  {
16  return false;
17  }
18  }
19 
20  return true;
21 }
22 
23 function array_is_associative ($array)
24 {
25  if ( is_array($array) && ! empty($array) )
26  {
27  for ( $iterator = count($array) - 1; $iterator; $iterator-- )
28  {
29  if ( ! array_key_exists($iterator, $array) ) { return true; }
30  }
31  return ! array_key_exists(0, $array);
32  }
33  return false;
34 }
35 
36 function setFields($object, array $fieldArray=null)
37 {
38  // helper method that allows creating objects and setting their properties based on an associative array passed as argument. Mimics functionality from PHP toolkit
39  $classname = get_class($object);
40  // a static map that maps class parameters to their types. needed for knowing which objects to create
41  $typesmap = $classname::$paramtypesmap;
42 
43  if (!isset ($typesmap)) {
44  // if the class does not have paramtypesmap, consider it empty
45  $typesmap = array();
46  }
47 
48  if ($fieldArray == null)
49  {
50  // nothign to do
51  return;
52  }
53 
54  foreach ($fieldArray as $fldName => $fldValue)
55  {
56  if (((is_null($fldValue) || $fldValue == "") && $fldValue !== false) || arrayValuesAreEmpty($fldValue))
57  {
58  //empty param
59  continue;
60  }
61 
62  if (!isset($typesmap[$fldName])) {
63  // the value is not a valid class atrribute
64  trigger_error("SetFields error: parameter \"" .$fldName . "\" is not a valid parameter for an object of class \"" . $classname . "\", it will be omitted", E_USER_WARNING);
65  continue;
66  }
67 
68  if ($fldValue === 'false')
69  {
70  // taken from the PHP toolkit, but is it really necessary?
71  $object->$fldName = FALSE;
72  }
73  elseif (is_object($fldValue))
74  {
75  $object->$fldName = $fldValue;
76  }
77  elseif (is_array($fldValue) && array_is_associative($fldValue))
78  {
79  // example: 'itemList' => array('item' => array($item1, $item2), 'replaceAll' => false)
80  if (substr($typesmap[$fldName],-2) == "[]") {
81  trigger_error("Trying to assign an object into an array parameter \"" .$fldName . "\" of class \"" . $classname . "\", it will be omitted", E_USER_WARNING);
82  continue;
83  }
84  $obj = new $typesmap[$fldName]();
85  setFields($obj, $fldValue);
86  $object->$fldName = $obj;
87  }
88  elseif (is_array($fldValue) && !array_is_associative($fldValue))
89  {
90  // array type
91  if (substr($typesmap[$fldName],-2) != "[]") {
92  // the type is not an array, skipping this value
93  trigger_error("Trying to assign an array value into parameter \"" .$fldName . "\" of class \"" . $classname . "\", it will be omitted", E_USER_WARNING);
94  continue;
95  }
96 
97  // get the base type - the string is of type <type>[]
98  $basetype = substr($typesmap[$fldName],0,-2);
99 
100  // example: 'item' => array($item1, $item2)
101  foreach ($fldValue as $item)
102  {
103  if (is_object($item))
104  {
105  // example: $item1 = new nsComplexObject('SalesOrderItem');
106  $val[] = $item;
107  }
108  elseif ($typesmap[$fldName] == "string")
109  {
110  // handle enums
111  $val[] = $item;
112  }
113  else
114  {
115  // example: $item2 = array( 'item' => new nsComplexObject('RecordRef', array('internalId' => '17')),
116  // 'quantity' => '3')
117  $obj = new $basetype();
118  setFields($obj, $item);
119  $val[] = $obj;
120  }
121  }
122 
123  $object->$fldName = $val;
124  }
125  else
126  {
127  $object->$fldName = $fldValue;
128  }
129  }
130 }
131 
132 function milliseconds()
133 {
134  $m = explode(' ',microtime());
135  return (int)round($m[0]*10000,4);
136 }
137 
138 function cleanUpNamespaces($xml_root)
139 {
140  $xml_root = str_replace('xsi:type', 'xsitype', $xml_root);
141  $record_element = new SimpleXMLElement($xml_root);
142 
143  foreach ($record_element->getDocNamespaces() as $name => $ns)
144  {
145  if ( $name != "" )
146  {
147  $xml_root = str_replace($name . ':', '', $xml_root);
148  }
149  }
150 
151  $record_element = new SimpleXMLElement($xml_root);
152 
153  foreach($record_element->children() as $field)
154  {
155  $field_element = new SimpleXMLElement($field->asXML());
156 
157  foreach ($field_element->getDocNamespaces() as $name2 => $ns2)
158  {
159  if ($name2 != "")
160  {
161  $xml_root = str_replace($name2 . ':', '', $xml_root);
162  }
163  }
164  }
165 
166  return $xml_root;
167 }
168 
169 class NSPHPClient {
170  private $nsversion = "2015_1r1";
171 
172  public $client = null;
173  public $passport = null;
174  private $soapHeaders = array();
175  private $userequest = true;
176  protected $classmap = null;
178 
179 
180  protected function __construct($wsdl=null, $options=array()) {
181  global $nshost, $nsendpoint;
182  global $nsaccount, $nsemail, $nsrole, $nspassword;
183  global $debuginfo;
184 
185  if (!isset($wsdl)) {
186  if (!isset($nshost)) {
187  throw new Exception('Webservice host must be specified');
188  }
189  if (!isset($nsendpoint)) {
190  throw new Exception('Webservice endpoint must be specified');
191  }
192  $wsdl = $nshost . "/wsdl/v" . $nsendpoint . "_0/netsuite.wsdl";
193  }
194 
195  if (!extension_loaded('soap')) {
196  // check for loaded SOAP extension
197  $soap_warning = 'The SOAP PHP extension is not loaded. Please modify the extension settings in php.ini accordingly.';
198  trigger_error($soap_warning, E_USER_WARNING);
199  }
200 
201  if (!extension_loaded('openssl') && substr($wsdl, 0, 5) == "https") {
202  // check for loaded SOAP extension
203  $soap_warning = 'The Open SSL PHP extension is not loaded and you are trying to use HTTPS protocol. Please modify the extension settings in php.ini accordingly.';
204  trigger_error($soap_warning, E_USER_WARNING);
205  }
206 
207  if ( $this->generated_from_endpoint != $nsendpoint ) {
208  // check for the endpoint compatibility failed, but it might still be compatible. Issue only warning
209  $endpoint_warning = 'The NetSuiteService classes were generated from the '.$this->generated_from_endpoint .' endpoint but you are running against ' . $nsendpoint;
210  trigger_error($endpoint_warning, E_USER_WARNING);
211  }
212 
213  $options['classmap'] = $this->classmap;
214  $options['trace'] = 1;
215  $options['connection_timeout'] = 5;
216  $options['cache_wsdl'] = WSDL_CACHE_BOTH;
217  $httpheaders = "PHP-SOAP/" . phpversion() . " + NetSuite PHP Toolkit " . $this->nsversion;
218 
219  $options['location'] = $nshost . "/services/NetSuitePort_" . $nsendpoint;
220  $options['keep_alive'] = false; // do not maintain http connection to the server.
221  $options['features'] = SOAP_SINGLE_ELEMENT_ARRAYS;
222 
223  $context = array('http' =>
224  array(
225  'header' => 'Authorization: dnwdjewdnwe'
226  )
227  );
228  //$options['stream_context'] = stream_context_create($context);
229 
230  if (isset($debuginfo)) {
231  $httpheaders .= "\r\nDebug: true";
232  $httpheaders .= "\r\nUser: " . $debuginfo["email"];
233  $httpheaders .= "\r\nPassword: " . $debuginfo["password"];
234  $httpheaders .= "\r\nIssue: " . $debuginfo["issue"];
235  }
236 
237  $options['user_agent'] = $httpheaders;
238  $this->setPassport($nsaccount, $nsemail, $nsrole, $nspassword);
239 
240  $this->client = new SoapClient($wsdl, $options);
241  }
242 
243  public function setPassport($nsaccount, $nsemail, $nsrole, $nspassword) {
244  $this->passport = new Passport();
245  $this->passport->account = $nsaccount;
246  $this->passport->email = $nsemail;
247  $this->passport->password = $nspassword;
248  $this->passport->role = new RecordRef();
249  $this->passport->role->internalId = $nsrole;
250  }
251 
252  public function useRequestLevelCredentials($option) {
253  $this->userequest = $option;
254  }
255 
256  public function setPreferences ($warningAsError = false, $disableMandatoryCustomFieldValidation = false, $disableSystemNotesForCustomFields = false, $ignoreReadOnlyFields = false)
257  {
258  $sp = new Preferences();
259  $sp->warningAsError = $warningAsError;
260  $sp->disableMandatoryCustomFieldValidation = $disableMandatoryCustomFieldValidation;
261  $sp->disableSystemNotesForCustomFields = $disableSystemNotesForCustomFields;
262  $sp->ignoreReadOnlyFields = $ignoreReadOnlyFields;
263 
264  $this->addHeader("preferences", $sp);
265  }
266 
267  public function clearPreferences() {
268  $this->clearHeader("preferences");
269  }
270 
271  public function setSearchPreferences ($bodyFieldsOnly = true, $pageSize = 50, $returnSearchColumns = true)
272  {
273  $sp = new SearchPreferences();
274  $sp->bodyFieldsOnly = $bodyFieldsOnly;
275  $sp->pageSize = $pageSize;
276  $sp->returnSearchColumns = $returnSearchColumns;
277 
278  $this->addHeader("searchPreferences", $sp);
279  }
280 
281  public function clearSearchPreferences() {
282  $this->clearHeader("searchPreferences");
283  }
284 
285  public function addHeader($header_name, $header) {
286  $this->soapHeaders[$header_name] = new SoapHeader("ns", $header_name, $header);
287  }
288  public function clearHeader($header_name) {
289  unset($this->soapHeaders[$header_name]);
290  }
291 
292  protected function makeSoapCall($operation, $parameter) {
293  if ($this->userequest) {
294  // use request level credentials, add passport as a SOAP header
295  $this->addHeader("passport", $this->passport);
296  // SoapClient, even with keep-alive set to false, keeps sending the JSESSIONID cookie back to the server on subsequent requests. Unsetting the cookie to prevent this.
297  $this->client->__setCookie("JSESSIONID");
298  } else {
299  $this->clearHeader("passport");
300  }
301 
302  $response = $this->client->__soapCall($operation, array($parameter), NULL, $this->soapHeaders);
303 
304  if ( file_exists(dirname(__FILE__) . '/nslog') ) {
305  // log the request and response into the nslog directory. Code taken from PHP toolkit
306  // REQUEST
307  $req = dirname(__FILE__) . '/nslog' . "/" . date("Ymd.His") . "." . milliseconds() . "-" . $operation . "-request.xml";
308  $Handle = fopen($req, 'w');
309  $Data = $this->client->__getLastRequest();
310 
311  $Data = cleanUpNamespaces($Data);
312 
313  $xml = simplexml_load_string($Data, 'SimpleXMLElement', LIBXML_NOCDATA);
314 
315  $passwordFields = $xml->xpath("//password | //password2 | //currentPassword | //newPassword | //newPassword2 | //ccNumber | //ccSecurityCode | //socialSecurityNumber");
316 
317  foreach ($passwordFields as &$pwdField) {
318  (string)$pwdField[0] = "[Content Removed for Security Reasons]";
319  }
320 
321  $stringCustomFields = $xml->xpath("//customField[@xsitype='StringCustomFieldRef']");
322 
323  foreach ($stringCustomFields as $field) {
324  (string)$field->value = "[Content Removed for Security Reasons]";
325  }
326 
327  $xml_string = str_replace('xsitype', 'xsi:type', $xml->asXML());
328 
329  fwrite($Handle, $xml_string);
330  fclose($Handle);
331 
332  // RESPONSE
333  $resp = dirname(__FILE__) . '/nslog' . "/" . date("Ymd.His") . "." . milliseconds() . "-" . $operation . "-response.xml";
334  $Handle = fopen($resp, 'w');
335  $Data = $this->client->__getLastResponse();
336  fwrite($Handle, $Data);
337  fclose($Handle);
338 
339  }
340 
341  return $response;
342 
343  }
344 
345 }
346 
347 
348 ?>
setPreferences($warningAsError=false, $disableMandatoryCustomFieldValidation=false, $disableSystemNotesForCustomFields=false, $ignoreReadOnlyFields=false)
cleanUpNamespaces($xml_root)
arrayValuesAreEmpty($array)
Definition: NSPHPClient.php:5
clearHeader($header_name)
clearSearchPreferences()
makeSoapCall($operation, $parameter)
array_is_associative($array)
Definition: NSPHPClient.php:23
setPassport($nsaccount, $nsemail, $nsrole, $nspassword)
useRequestLevelCredentials($option)
__construct($wsdl=null, $options=array())
addHeader($header_name, $header)
setFields($object, array $fieldArray=null)
Definition: NSPHPClient.php:36
setSearchPreferences($bodyFieldsOnly=true, $pageSize=50, $returnSearchColumns=true)
milliseconds()