7
7
namespace Magento \Dhl \Model ;
8
8
9
9
use Magento \Catalog \Model \Product \Type ;
10
+ use Magento \Framework \App \ObjectManager ;
10
11
use Magento \Framework \App \ProductMetadataInterface ;
12
+ use Magento \Framework \Async \CallbackDeferred ;
13
+ use Magento \Framework \Async \ProxyDeferredFactory ;
14
+ use Magento \Framework \HTTP \AsyncClient \HttpResponseDeferredInterface ;
15
+ use Magento \Framework \HTTP \AsyncClient \Request ;
16
+ use Magento \Framework \HTTP \AsyncClientInterface ;
11
17
use Magento \Framework \Module \Dir ;
12
18
use Magento \Sales \Exception \DocumentValidationException ;
13
19
use Magento \Sales \Model \Order \Shipment ;
@@ -197,6 +203,8 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
197
203
198
204
/**
199
205
* @var \Magento\Framework\HTTP\ZendClientFactory
206
+ * @deprecated Use asynchronous client.
207
+ * @see $httpClient
200
208
*/
201
209
protected $ _httpClientFactory ;
202
210
@@ -219,6 +227,16 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
219
227
*/
220
228
private $ productMetadata ;
221
229
230
+ /**
231
+ * @var AsyncClientInterface
232
+ */
233
+ private $ httpClient ;
234
+
235
+ /**
236
+ * @var ProxyDeferredFactory
237
+ */
238
+ private $ proxyDeferredFactory ;
239
+
222
240
/**
223
241
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
224
242
* @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
@@ -247,6 +265,8 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
247
265
* @param array $data
248
266
* @param \Magento\Dhl\Model\Validator\XmlValidator|null $xmlValidator
249
267
* @param ProductMetadataInterface|null $productMetadata
268
+ * @param AsyncClientInterface|null $httpClient
269
+ * @param ProxyDeferredFactory|null $proxyDeferredFactory
250
270
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
251
271
*/
252
272
public function __construct (
@@ -276,7 +296,9 @@ public function __construct(
276
296
\Magento \Framework \HTTP \ZendClientFactory $ httpClientFactory ,
277
297
array $ data = [],
278
298
\Magento \Dhl \Model \Validator \XmlValidator $ xmlValidator = null ,
279
- ProductMetadataInterface $ productMetadata = null
299
+ ProductMetadataInterface $ productMetadata = null ,
300
+ ?AsyncClientInterface $ httpClient = null ,
301
+ ?ProxyDeferredFactory $ proxyDeferredFactory = null
280
302
) {
281
303
$ this ->readFactory = $ readFactory ;
282
304
$ this ->_carrierHelper = $ carrierHelper ;
@@ -308,10 +330,11 @@ public function __construct(
308
330
if ($ this ->getConfigData ('content_type ' ) == self ::DHL_CONTENT_TYPE_DOC ) {
309
331
$ this ->_freeMethod = 'free_method_doc ' ;
310
332
}
311
- $ this ->xmlValidator = $ xmlValidator
312
- ?: \Magento \Framework \App \ObjectManager::getInstance ()->get (XmlValidator::class);
313
- $ this ->productMetadata = $ productMetadata
314
- ?: \Magento \Framework \App \ObjectManager::getInstance ()->get (ProductMetadataInterface::class);
333
+ $ this ->xmlValidator = $ xmlValidator ?? ObjectManager::getInstance ()->get (XmlValidator::class);
334
+ $ this ->productMetadata = $ productMetadata ?? ObjectManager::getInstance ()->get (ProductMetadataInterface::class);
335
+ $ this ->httpClient = $ httpClient ?? ObjectManager::getInstance ()->get (AsyncClientInterface::class);
336
+ $ this ->proxyDeferredFactory = $ proxyDeferredFactory
337
+ ?? ObjectManager::getInstance ()->get (ProxyDeferredFactory::class);
315
338
}
316
339
317
340
/**
@@ -348,7 +371,6 @@ public function collectRates(RateRequest $request)
348
371
349
372
$ requestDhl = clone $ request ;
350
373
$ this ->setStore ($ requestDhl ->getStoreId ());
351
-
352
374
$ origCompanyName = $ this ->_getDefaultValue (
353
375
$ requestDhl ->getOrigCompanyName (),
354
376
\Magento \Store \Model \Information::XML_PATH_STORE_INFO_NAME
@@ -357,18 +379,27 @@ public function collectRates(RateRequest $request)
357
379
$ origState = $ this ->_getDefaultValue ($ requestDhl ->getOrigState (), Shipment::XML_PATH_STORE_REGION_ID );
358
380
$ origCity = $ this ->_getDefaultValue ($ requestDhl ->getOrigCity (), Shipment::XML_PATH_STORE_CITY );
359
381
$ origPostcode = $ this ->_getDefaultValue ($ requestDhl ->getOrigPostcode (), Shipment::XML_PATH_STORE_ZIP );
360
-
361
382
$ requestDhl ->setOrigCompanyName ($ origCompanyName )
362
383
->setCountryId ($ origCountryId )
363
384
->setOrigState ($ origState )
364
385
->setOrigCity ($ origCity )
365
386
->setOrigPostal ($ origPostcode );
366
387
$ this ->setRequest ($ requestDhl );
367
-
368
- $ this ->_result = $ this ->_getQuotes ();
369
- $ this ->_updateFreeMethodQuote ($ request );
370
-
371
- return $ this ->_result ;
388
+ //Loading quotes
389
+ //Saving $result to use proper result with the callback
390
+ $ this ->_result = $ result = $ this ->_getQuotes ();
391
+ //After quotes are loaded parsing the response.
392
+ return $ this ->proxyDeferredFactory ->createFor (
393
+ Result::class,
394
+ new CallbackDeferred (
395
+ function () use ($ request , $ result ) {
396
+ $ this ->_result = $ result ;
397
+ $ this ->_updateFreeMethodQuote ($ request );
398
+
399
+ return $ this ->_result ;
400
+ }
401
+ )
402
+ );
372
403
}
373
404
374
405
/**
@@ -715,6 +746,7 @@ protected function _getWeight($weight, $maxWeight = false, $configWeightUnit = f
715
746
* @return array
716
747
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
717
748
* @SuppressWarnings(PHPMD.NPathComplexity)
749
+ * phpcs:disable Generic.Metrics.NestingLevel
718
750
*/
719
751
protected function _getAllItems ()
720
752
{
@@ -799,6 +831,7 @@ protected function _getAllItems()
799
831
800
832
return $ fullItems ;
801
833
}
834
+ //phpcs:enable
802
835
803
836
/**
804
837
* Make pieces
@@ -931,56 +964,126 @@ protected function _addDimension($nodePiece)
931
964
}
932
965
933
966
/**
934
- * Get shipping quotes
967
+ * Process response received from DHL's API for quotes.
935
968
*
936
- * @return \Magento\Framework\Model\AbstractModel|Result
969
+ * @param array $responsesData
970
+ * @return Error|Result
937
971
*/
938
- protected function _getQuotes ( )
972
+ private function processQuotesResponses ( array $ responsesData )
939
973
{
940
- $ responseBody = '' ;
941
- try {
942
- for ($ offset = 0 ; $ offset <= self ::UNAVAILABLE_DATE_LOOK_FORWARD ; $ offset ++) {
943
- $ debugPoint = [];
944
-
945
- $ requestXml = $ this ->_buildQuotesRequestXml ();
946
- $ date = date (self ::REQUEST_DATE_FORMAT , strtotime ($ this ->_getShipDate () . " + {$ offset } days " ));
947
- $ this ->_setQuotesRequestXmlDate ($ requestXml , $ date );
948
-
949
- $ request = $ requestXml ->asXML ();
950
- $ debugPoint ['request ' ] = $ this ->filterDebugData ($ request );
951
- $ responseBody = $ this ->_getCachedQuotes ($ request );
952
- $ debugPoint ['from_cache ' ] = $ responseBody === null ;
953
-
954
- if ($ debugPoint ['from_cache ' ]) {
955
- $ responseBody = $ this ->_getQuotesFromServer ($ request );
956
- }
957
-
958
- $ debugPoint ['response ' ] = $ this ->filterDebugData ($ responseBody );
959
-
960
- $ bodyXml = $ this ->_xmlElFactory ->create (['data ' => $ responseBody ]);
974
+ usort (
975
+ $ responsesData ,
976
+ function (array $ a , array $ b ): int {
977
+ return $ a ['date ' ] <=> $ b ['date ' ];
978
+ }
979
+ );
980
+ /** @var string $lastResponse */
981
+ $ lastResponse = '' ;
982
+ //Processing different dates
983
+ foreach ($ responsesData as $ responseData ) {
984
+ $ debugPoint = [];
985
+ $ debugPoint ['request ' ] = $ this ->filterDebugData ($ responseData ['request ' ]);
986
+ $ debugPoint ['response ' ] = $ this ->filterDebugData ($ responseData ['body ' ]);
987
+ $ debugPoint ['from_cache ' ] = $ responseData ['from_cache ' ];
988
+ $ unavailable = false ;
989
+ try {
990
+ //Getting availability
991
+ $ bodyXml = $ this ->_xmlElFactory ->create (['data ' => $ responseData ['body ' ]]);
961
992
$ code = $ bodyXml ->xpath ('//GetQuoteResponse/Note/Condition/ConditionCode ' );
962
993
if (isset ($ code [0 ]) && (int )$ code [0 ] == self ::CONDITION_CODE_SERVICE_DATE_UNAVAILABLE ) {
963
- $ debugPoint ['info ' ] = sprintf (__ ("DHL service is not available at %s date " ), $ date );
964
- } else {
965
- $ this ->_debug ($ debugPoint );
966
- break ;
994
+ $ debugPoint ['info ' ] = sprintf (
995
+ __ ("DHL service is not available at %s date " ),
996
+ $ responseData ['date ' ]
997
+ );
998
+ $ unavailable = true ;
967
999
}
968
-
969
- $ this ->_setCachedQuotes ($ request , $ responseBody );
1000
+ } catch (\Throwable $ exception ) {
1001
+ //Failed to read response
1002
+ $ unavailable = true ;
1003
+ $ this ->_errors [$ exception ->getCode ()] = $ exception ->getMessage ();
1004
+ }
1005
+ if ($ unavailable ) {
1006
+ //Cannot get rates.
970
1007
$ this ->_debug ($ debugPoint );
1008
+ break ;
971
1009
}
972
- } catch (\Exception $ e ) {
973
- $ this ->_errors [$ e ->getCode ()] = $ e ->getMessage ();
1010
+ //Caching rates
1011
+ $ this ->_setCachedQuotes ($ responseData ['request ' ], $ responseData ['body ' ]);
1012
+ $ this ->_debug ($ debugPoint );
1013
+ //Will only process rates available for the latest date possible.
1014
+ $ lastResponse = $ responseData ['body ' ];
974
1015
}
975
1016
976
- return $ this ->_parseResponse ($ responseBody );
1017
+ return $ this ->_parseResponse ($ lastResponse );
1018
+ }
1019
+
1020
+ /**
1021
+ * Get shipping quotes
1022
+ *
1023
+ * @return \Magento\Framework\Model\AbstractModel|Result
1024
+ */
1025
+ protected function _getQuotes ()
1026
+ {
1027
+ $ responseBodies = [];
1028
+ /** @var HttpResponseDeferredInterface[][] $deferredResponses */
1029
+ $ deferredResponses = [];
1030
+ $ requestXml = $ this ->_buildQuotesRequestXml ();
1031
+ for ($ offset = 0 ; $ offset <= self ::UNAVAILABLE_DATE_LOOK_FORWARD ; $ offset ++) {
1032
+ $ date = date (self ::REQUEST_DATE_FORMAT , strtotime ($ this ->_getShipDate () . " + {$ offset } days " ));
1033
+ $ this ->_setQuotesRequestXmlDate ($ requestXml , $ date );
1034
+ $ request = $ requestXml ->asXML ();
1035
+ $ responseBody = $ this ->_getCachedQuotes ($ request );
1036
+
1037
+ if ($ responseBody === null ) {
1038
+ $ deferredResponses [] = [
1039
+ 'deferred ' => $ this ->httpClient ->request (
1040
+ new Request (
1041
+ (string )$ this ->getConfigData ('gateway_url ' ),
1042
+ Request::METHOD_POST ,
1043
+ ['Content-Type ' => 'application/xml ' ],
1044
+ utf8_encode ($ request )
1045
+ )
1046
+ ),
1047
+ 'date ' => $ date ,
1048
+ 'request ' => $ request
1049
+ ];
1050
+ } else {
1051
+ $ responseBodies [] = [
1052
+ 'body ' => $ responseBody ,
1053
+ 'date ' => $ date ,
1054
+ 'request ' => $ request ,
1055
+ 'from_cache ' => true
1056
+ ];
1057
+ }
1058
+ }
1059
+
1060
+ return $ this ->proxyDeferredFactory ->createFor (
1061
+ Result::class,
1062
+ new CallbackDeferred (
1063
+ function () use ($ deferredResponses , $ responseBodies ) {
1064
+ //Loading rates not found in cache
1065
+ foreach ($ deferredResponses as $ deferredResponseData ) {
1066
+ $ responseBodies [] = [
1067
+ 'body ' => $ deferredResponseData ['deferred ' ]->get ()->getBody (),
1068
+ 'date ' => $ deferredResponseData ['date ' ],
1069
+ 'request ' => $ deferredResponseData ['request ' ],
1070
+ 'from_cache ' => false
1071
+ ];
1072
+ }
1073
+
1074
+ return $ this ->processQuotesResponses ($ responseBodies );
1075
+ }
1076
+ )
1077
+ );
977
1078
}
978
1079
979
1080
/**
980
1081
* Get shipping quotes from DHL service
981
1082
*
982
1083
* @param string $request
983
1084
* @return string
1085
+ * @deprecated Use asynchronous client.
1086
+ * @see _getQuotes()
984
1087
*/
985
1088
protected function _getQuotesFromServer ($ request )
986
1089
{
@@ -1568,21 +1671,23 @@ protected function _doRequest()
1568
1671
$ xml ->addChild ('LabelImageFormat ' , 'PDF ' , '' );
1569
1672
1570
1673
$ request = $ xml ->asXML ();
1571
- if (! $ request && !(mb_detect_encoding ($ request ) == 'UTF-8 ' )) {
1674
+ if ($ request && !(mb_detect_encoding ($ request ) == 'UTF-8 ' )) {
1572
1675
$ request = utf8_encode ($ request );
1573
1676
}
1574
1677
1575
1678
$ responseBody = $ this ->_getCachedQuotes ($ request );
1576
1679
if ($ responseBody === null ) {
1577
1680
$ debugData = ['request ' => $ this ->filterDebugData ($ request )];
1578
1681
try {
1579
- /** @var \Magento\Framework\HTTP\ZendClient $client */
1580
- $ client = $ this ->_httpClientFactory ->create ();
1581
- $ client ->setUri ((string )$ this ->getConfigData ('gateway_url ' ));
1582
- $ client ->setConfig (['maxredirects ' => 0 , 'timeout ' => 30 ]);
1583
- $ client ->setRawData ($ request );
1584
- $ responseBody = $ client ->request (\Magento \Framework \HTTP \ZendClient::POST )->getBody ();
1585
- $ responseBody = utf8_decode ($ responseBody );
1682
+ $ response = $ this ->httpClient ->request (
1683
+ new Request (
1684
+ (string )$ this ->getConfigData ('gateway_url ' ),
1685
+ Request::METHOD_POST ,
1686
+ ['Content-Type ' => 'application/xml ' ],
1687
+ $ request
1688
+ )
1689
+ );
1690
+ $ responseBody = utf8_decode ($ response ->get ()->getBody ());
1586
1691
$ debugData ['result ' ] = $ this ->filterDebugData ($ responseBody );
1587
1692
$ this ->_setCachedQuotes ($ request , $ responseBody );
1588
1693
} catch (\Exception $ e ) {
@@ -1743,12 +1848,15 @@ protected function _getXMLTracking($trackings)
1743
1848
if ($ responseBody === null ) {
1744
1849
$ debugData = ['request ' => $ this ->filterDebugData ($ request )];
1745
1850
try {
1746
- /** @var \Magento\Framework\HTTP\ZendClient $client */
1747
- $ client = $ this ->_httpClientFactory ->create ();
1748
- $ client ->setUri ((string )$ this ->getConfigData ('gateway_url ' ));
1749
- $ client ->setConfig (['maxredirects ' => 0 , 'timeout ' => 30 ]);
1750
- $ client ->setRawData ($ request );
1751
- $ responseBody = $ client ->request (\Magento \Framework \HTTP \ZendClient::POST )->getBody ();
1851
+ $ response = $ this ->httpClient ->request (
1852
+ new Request (
1853
+ (string )$ this ->getConfigData ('gateway_url ' ),
1854
+ Request::METHOD_POST ,
1855
+ ['Content-Type ' => 'application/xml ' ],
1856
+ $ request
1857
+ )
1858
+ );
1859
+ $ responseBody = $ response ->get ()->getBody ();
1752
1860
$ debugData ['result ' ] = $ this ->filterDebugData ($ responseBody );
1753
1861
$ this ->_setCachedQuotes ($ request , $ responseBody );
1754
1862
} catch (\Exception $ e ) {
@@ -1850,6 +1958,7 @@ protected function _parseXmlTrackingResponse($trackings, $response)
1850
1958
$ result ->append ($ error );
1851
1959
}
1852
1960
}
1961
+ $ this ->_errors = [];
1853
1962
1854
1963
$ this ->_result = $ result ;
1855
1964
}
@@ -1944,6 +2053,7 @@ protected function _prepareShippingLabelContent(\SimpleXMLElement $xml)
1944
2053
}
1945
2054
$ result ->setTrackingNumber ((string )$ xml ->AirwayBillNumber );
1946
2055
$ labelContent = (string )$ xml ->LabelImage ->OutputImage ;
2056
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
1947
2057
$ result ->setShippingLabelContent (base64_decode ($ labelContent ));
1948
2058
} catch (\Exception $ e ) {
1949
2059
throw new \Magento \Framework \Exception \LocalizedException (__ ($ e ->getMessage ()));
0 commit comments