@@ -235,7 +235,13 @@ protected function login()
235235 $ this ->pxSessionId = $ this ->extractSessionId ($ header );
236236
237237 if (empty ($ this ->pxSessionId )) {
238- throw new HttpClientException ('Failed to retrieve PxSessionId from login response. ' , 401 , $ this ->request , $ this ->response );
238+ $ responseBody = substr ($ response , $ headerSize );
239+ $ parsedBody = json_decode ($ responseBody );
240+ $ errorMessage = 'Failed to retrieve PxSessionId from login response. ' ;
241+ if (isset ($ parsedBody ->Message )) {
242+ $ errorMessage .= ' Proffix API Error: ' . $ parsedBody ->Message ;
243+ }
244+ throw new HttpClientException ($ errorMessage , 401 , $ this ->request , $ this ->response );
239245 }
240246
241247 return $ this ->pxSessionId ;
@@ -390,23 +396,7 @@ protected function getResponseHeaders()
390396 */
391397 protected function createResponse ()
392398 {
393-
394- // Set response headers.
395- $ this ->responseHeaders = '' ;
396- \curl_setopt ($ this ->ch , CURLOPT_HEADERFUNCTION , function ($ _ , $ headers ) {
397- $ this ->responseHeaders .= $ headers ;
398- return \strlen ($ headers );
399- });
400-
401- // Get response data.
402- $ body = \curl_exec ($ this ->ch );
403- $ code = \curl_getinfo ($ this ->ch , CURLINFO_HTTP_CODE );
404- $ headers = $ this ->getResponseHeaders ();
405-
406- // Register response.
407- $ this ->response = new Response ($ code , $ headers , $ body );
408-
409- return $ this ->getResponse ();
399+ $ this ->response = new Response ();
410400 }
411401
412402 /**
@@ -509,43 +499,58 @@ protected function processResponse()
509499 return $ parsedResponse ;
510500 }
511501
502+
503+
504+ public function request ($ endpoint , $ method , $ data = [], $ parameters = [], $ login = true )
505+ {
506+ $ this ->prepareRequest ($ endpoint , $ method , $ data , $ parameters , $ login );
507+ return $ this ->executeCurl (true );
508+ }
509+
512510 /**
513511 * @param $endpoint
514512 * @param $method
515513 * @param array $data
516514 * @param array $parameters
517- * @return mixed
515+ * @return Response
518516 * @throws HttpClientException
519517 */
520- public function request ($ endpoint , $ method , $ data = [], $ parameters = [], $ login = true )
518+ public function rawRequest ($ endpoint , $ method , $ data = [], $ parameters = []): Response
519+ {
520+ $ this ->prepareRequest ($ endpoint , $ method , $ data , $ parameters , true ); // Login is always required for raw requests
521+ return $ this ->executeCurl (false );
522+ }
523+
524+ /**
525+ * @param $endpoint
526+ * @param $method
527+ * @param $data
528+ * @param $parameters
529+ * @param $login
530+ * @throws HttpClientException
531+ */
532+ private function prepareRequest ($ endpoint , $ method , $ data , $ parameters , $ login )
521533 {
522534 $ this ->initCurl ();
523535
524536 // Create the request object for the main operation.
525- // This will be available if login() throws an exception.
526537 $ this ->createRequest ($ endpoint , $ method , $ data , $ parameters );
527538
528- // If login is required, it's performed first.
529- // login() will use the current $this->ch, temporarily setting options for the login call.
539+ // If login is required, it's performed first.
530540 if ($ login && empty ($ this ->pxSessionId )) {
531- $ this ->login (); // This populates $this->pxSessionId if successful
541+ $ this ->login ();
532542 }
533543
534- // Now, apply default cURL settings for the MAIN request.
535- // This sets the main request's URL (from $this->request), CURLOPT_HEADER=false, etc.,
536- // effectively overriding any temporary settings login() might have applied to $this->ch.
537- $ this ->setDefaultCurlSettings ();
538-
539- // Clear any headers from a potential previous login call on the same handle
540- \curl_setopt ($ this ->ch , CURLOPT_HTTPHEADER , []);
544+ // Apply default cURL settings for the MAIN request.
545+ $ this ->setDefaultCurlSettings ();
541546
542- // Now, get the final headers for this specific request (which will include PxSessionId if login occurred)
547+ // Get the final headers for this specific request (which will include PxSessionId if login occurred)
543548 $ finalRequestHeaders = $ this ->getRequestHeaders (!empty ($ data ));
544549 $ rawFinalRequestHeaders = [];
545550 foreach ($ finalRequestHeaders as $ key => $ value ) {
546551 $ rawFinalRequestHeaders [] = $ key . ': ' . $ value ;
547552 }
548- \curl_setopt ($ this ->ch , CURLOPT_HTTPHEADER , $ rawFinalRequestHeaders ); // Set the final headers for the main API call
553+ \curl_setopt ($ this ->ch , CURLOPT_HTTPHEADER , $ rawFinalRequestHeaders );
549554
550555 // Setup method.
551556 $ this ->setupMethod ($ method );
@@ -557,11 +562,56 @@ public function request($endpoint, $method, $data = [], $parameters = [], $login
557562 }
558563
559564 $ this ->createResponse ();
560- // Process response once and store it
561- $ processedResponse = $ this ->processResponse ();
562- $ this ->lookForErrors ($ processedResponse );
565+ }
566+
567+ /**
568+ * @param bool $processJson
569+ * @return mixed|Response
570+ * @throws HttpClientException
571+ */
572+ private function executeCurl (bool $ processJson = true )
573+ {
574+ // Set response headers callback
575+ $ this ->responseHeaders = '' ;
576+ \curl_setopt ($ this ->ch , CURLOPT_HEADERFUNCTION , function ($ curl , $ header ) {
577+ $ this ->responseHeaders .= $ header ;
578+ return strlen ($ header );
579+ });
580+
581+ $ body = curl_exec ($ this ->ch );
563582
564- return $ processedResponse ;
583+ if (curl_errno ($ this ->ch )) {
584+ throw new HttpClientException ('cURL error: ' . curl_error ($ this ->ch ), curl_errno ($ this ->ch ), $ this ->request , $ this ->response );
585+ }
586+
587+ $ this ->response ->setBody ($ body );
588+ $ this ->response ->setCode (curl_getinfo ($ this ->ch , CURLINFO_HTTP_CODE ));
589+ $ this ->response ->setHeaders ($ this ->getResponseHeaders ());
590+
591+ if ($ processJson ) {
592+ // processResponse will decode and also call lookForErrors
593+ return $ this ->processResponse ();
594+ }
595+
596+ // For raw requests, we only check for non-2xx status codes.
597+ if (!in_array ($ this ->response ->getCode (), ['200 ' , '201 ' , '202 ' , '204 ' ])) {
598+ // Try to parse the body as JSON to get a detailed error message
599+ $ parsedError = \json_decode ($ this ->response ->getBody ());
600+ if (JSON_ERROR_NONE === json_last_error ()) {
601+ // It's a JSON error response, pass it to lookForErrors
602+ $ this ->lookForErrors ($ parsedError );
603+ } else {
604+ // Not a JSON error, create a generic exception
605+ throw new HttpClientException (
606+ 'HTTP Error ' . $ this ->response ->getCode (),
607+ $ this ->response ->getCode (),
608+ $ this ->request ,
609+ $ this ->response
610+ );
611+ }
612+ }
613+
614+ return $ this ->response ;
565615 }
566616
567617 /**
0 commit comments