GetLatLngFromAddress.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\InventoryDistanceBasedSourceSelection\Model\DistanceProvider\GoogleMap;
  8. use Magento\Framework\Exception\LocalizedException;
  9. use Magento\Framework\HTTP\ClientInterface;
  10. use Magento\Framework\Serialize\Serializer\Json;
  11. use Magento\InventoryDistanceBasedSourceSelection\Model\Convert\AddressToComponentsString;
  12. use Magento\InventoryDistanceBasedSourceSelection\Model\Convert\AddressToQueryString;
  13. use Magento\InventoryDistanceBasedSourceSelection\Model\Convert\AddressToString;
  14. use Magento\InventorySourceSelectionApi\Api\Data\AddressInterface;
  15. use Magento\InventoryDistanceBasedSourceSelectionApi\Api\Data\LatLngInterface;
  16. use Magento\InventoryDistanceBasedSourceSelectionApi\Api\Data\LatLngInterfaceFactory;
  17. use Magento\InventoryDistanceBasedSourceSelectionApi\Api\GetLatLngFromAddressInterface;
  18. /**
  19. * @inheritdoc
  20. */
  21. class GetLatLngFromAddress implements GetLatLngFromAddressInterface
  22. {
  23. private const GOOGLE_ENDPOINT = 'https://maps.google.com/maps/api/geocode/json';
  24. /**
  25. * @var array
  26. */
  27. private $latLngCache = [];
  28. /**
  29. * @var ClientInterface
  30. */
  31. private $client;
  32. /**
  33. * @var LatLngInterface
  34. */
  35. private $latLngInterfaceFactory;
  36. /**
  37. * @var Json
  38. */
  39. private $json;
  40. /**
  41. * @var GetApiKey
  42. */
  43. private $getApiKey;
  44. /**
  45. * @var AddressToComponentsString
  46. */
  47. private $addressToComponentsString;
  48. /**
  49. * @var AddressToString
  50. */
  51. private $addressToString;
  52. /**
  53. * @var AddressToQueryString
  54. */
  55. private $addressToQueryString;
  56. /**
  57. * GetLatLngFromAddress constructor.
  58. *
  59. * @param ClientInterface $client
  60. * @param LatLngInterfaceFactory $latLngInterfaceFactory
  61. * @param Json $json
  62. * @param GetApiKey $getApiKey
  63. * @param AddressToComponentsString $addressToComponentsString
  64. * @param AddressToQueryString $addressToQueryString
  65. * @param AddressToString $addressToString
  66. */
  67. public function __construct(
  68. ClientInterface $client,
  69. LatLngInterfaceFactory $latLngInterfaceFactory,
  70. Json $json,
  71. GetApiKey $getApiKey,
  72. AddressToComponentsString $addressToComponentsString,
  73. AddressToQueryString $addressToQueryString,
  74. AddressToString $addressToString
  75. ) {
  76. $this->client = $client;
  77. $this->latLngInterfaceFactory = $latLngInterfaceFactory;
  78. $this->json = $json;
  79. $this->getApiKey = $getApiKey;
  80. $this->addressToComponentsString = $addressToComponentsString;
  81. $this->addressToString = $addressToString;
  82. $this->addressToQueryString = $addressToQueryString;
  83. }
  84. /**
  85. * @inheritdoc
  86. * @throws LocalizedException
  87. */
  88. public function execute(AddressInterface $address): LatLngInterface
  89. {
  90. $cacheKey = $addressString = $this->addressToString->execute($address);
  91. if (!isset($this->latLngCache[$cacheKey])) {
  92. $queryString = http_build_query([
  93. 'key' => $this->getApiKey->execute(),
  94. 'components' => $this->addressToComponentsString->execute($address),
  95. 'address' => $this->addressToQueryString->execute($address),
  96. ]);
  97. $this->client->get(self::GOOGLE_ENDPOINT . '?' . $queryString);
  98. if ($this->client->getStatus() !== 200) {
  99. throw new LocalizedException(__('Unable to connect google API for geocoding'));
  100. }
  101. $res = $this->json->unserialize($this->client->getBody());
  102. if ($res['status'] !== 'OK') {
  103. throw new LocalizedException(__('Unable to geocode address %1', $addressString));
  104. }
  105. $location = $res['results'][0]['geometry']['location'];
  106. $this->latLngCache[$cacheKey] = $this->latLngInterfaceFactory->create([
  107. 'lat' => (float)$location['lat'],
  108. 'lng' => (float)$location['lng'],
  109. ]);
  110. }
  111. return $this->latLngCache[$cacheKey];
  112. }
  113. }