vendor/store.shopware.com/wexofreeshipping/src/Subscriber/GeoLocationInCart.php line 56

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Wexo\FreeShipping\Subscriber;
  3. use GuzzleHttp\Client;
  4. use GuzzleHttp\Exception\GuzzleException;
  5. use Shopware\Core\Checkout\Cart\Cart;
  6. use Shopware\Core\Checkout\Cart\Event\CartChangedEvent;
  7. use Shopware\Core\Checkout\Cart\Event\CartCreatedEvent;
  8. use Shopware\Core\Checkout\Cart\Event\CartDeletedEvent;
  9. use Shopware\Core\Checkout\Cart\Event\CartMergedEvent;
  10. use Shopware\Core\Checkout\Cart\Event\CartSavedEvent;
  11. use Shopware\Core\Checkout\Cart\Event\CartVerifyPersistEvent;
  12. use Shopware\Core\Framework\Context;
  13. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  16. use Shopware\Core\Framework\Struct\ArrayStruct;
  17. use Shopware\Core\System\SystemConfig\SystemConfigService;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. class GeoLocationInCart implements EventSubscriberInterface
  20. {
  21.     const GEO_LOCATION_EXTENSION_LABEL 'wexo_geo_location';
  22.     const GEO_LOCATION_EXTENSION_IP_LABEL 'wexo_geo_location_ip';
  23.     const GEO_LOCATION_EXTENSION_COUNTRY_LABEL 'wexo_geo_location_country';
  24.     const GEO_LOCATION_EXTENSION_COUNTRY_ID_LABEL 'wexo_geo_location_country_id';
  25.     private const API_URL "https://api.ipapi.com/api";
  26.     private SystemConfigService $configService;
  27.     private EntityRepositoryInterface $countryTranslationRepository;
  28.     public function __construct(
  29.         SystemConfigService $configService,
  30.         EntityRepositoryInterface $countryTranslationRepository
  31.     ) {
  32.         $this->configService $configService;
  33.         $this->countryTranslationRepository $countryTranslationRepository;
  34.     }
  35.     public static function getSubscribedEvents()
  36.     {
  37.         return [
  38.             CartCreatedEvent::class => "setGeoLocationOnCartCreated",
  39.             CartChangedEvent::class => "setGeoLocationOnCartChanged",
  40.             CartMergedEvent::class => "setGeoLocationOnCartChanged",
  41.             CartSavedEvent::class => "setGeoLocationOnCartChanged",
  42.             CartVerifyPersistEvent::class => "setGeoLocationOnCartChanged",
  43.         ];
  44.     }
  45.     public function setGeoLocationOnCartCreated(CartCreatedEvent $event): void
  46.     {
  47.         $this->addCartGeoLocationExtension($event->getCart());
  48.     }
  49.     public function setGeoLocationOnCartChanged($event): void
  50.     {
  51.         $this->addCartGeoLocationExtension($event->getCart());
  52.     }
  53.     private function addCartGeoLocationExtension(Cart $cart): void
  54.     {
  55.         /* If Geo Location already set, and ip has not changed, then do nothing */
  56.         $geoLocationStruct $cart->getExtension(self::GEO_LOCATION_EXTENSION_LABEL);
  57.         if ($geoLocationStruct !== null && $cart->getExtension(GeoLocationInCart::GEO_LOCATION_EXTENSION_LABEL)
  58.                 ->get(GeoLocationInCart::GEO_LOCATION_EXTENSION_IP_LABEL) === $this->getIPAddress()) {
  59.             return;
  60.         }
  61.         $ip $this->getIPAddress();
  62.         $country $this->getCountryByIp($ip);
  63.         $countryId $this->getCountryId($country);
  64.         $struct = new ArrayStruct([
  65.               self::GEO_LOCATION_EXTENSION_IP_LABEL => $ip,
  66.               self::GEO_LOCATION_EXTENSION_COUNTRY_ID_LABEL => $countryId
  67.           ]);
  68.         $cart->addExtension(self::GEO_LOCATION_EXTENSION_LABEL$struct);
  69.     }
  70.     private function getCountryByIp(string $ipAddress): ?string
  71.     {
  72.         $apiKey $this->configService->get("WexoFreeShipping.config.ipApiKey");
  73.         $country "";
  74.         try {
  75.             $client = new Client([
  76.                 'base_uri' => sprintf("%s/%s?access_key=%s"self::API_URL$ipAddress$apiKey),
  77.                 'headers' => [
  78.                     "Accept" => "*/*",
  79.                     "Accept-Encoding" => "gzip, deflate",
  80.                     "Accept-Version" => "v10",
  81.                     "Host" => self::API_URL,
  82.                     "cache-control" => "no-cache",
  83.                 ]
  84.             ]);
  85.             $response $client->request(
  86.                 'GET'
  87.             );
  88.             $responseData json_decode($response->getBody()->getContents());
  89.             if ($response->getStatusCode() === 200 &&
  90.                 $responseData !== null &&
  91.                 property_exists($responseData"country_name") === true) {
  92.                 $country $responseData->country_name;
  93.             }
  94.         } catch (GuzzleException $e) {
  95.         }
  96.         return $country;
  97.     }
  98.     private function getCountryId($countryName): string
  99.     {
  100.         if ($countryName === "") {
  101.             return "";
  102.         }
  103.         $criteria = new Criteria();
  104.         $criteria->addFilter(new EqualsFilter('name'$countryName));
  105.         $countryId $this->countryTranslationRepository->searchIds($criteriaContext::createDefaultContext());
  106.         if ($countryId->getTotal() > 0) {
  107.             return $countryId->getIds()[0]['country_id'];
  108.         }
  109.         return "";
  110.     }
  111.     private function getIPAddress(): string
  112.     {
  113.         /* Swedish test ip 185.141.152.145 */
  114.         /* Danish test Ip 82.192.170.42 */
  115.         /* origin: https://www.javatpoint.com/how-to-get-the-ip-address-in-php */
  116.         if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  117.             $ip $_SERVER['HTTP_CLIENT_IP'];
  118.         } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  119.             $ip $_SERVER['HTTP_X_FORWARDED_FOR'];
  120.         } elseif (isset($_SERVER['REMOTE_ADDR'])) {
  121.             $ip $_SERVER['REMOTE_ADDR'];
  122.         } else {
  123.             $ip "127.0.0.1";
  124.         }
  125.         return $ip;
  126.     }
  127. }