Advertisement
shapoval

GeoIp.php

Mar 29th, 2022
1,021
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.23 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Lustery\Service;
  4.  
  5. use App\Common\Helper\Config;
  6. use App\Common\Service\Logger\Log;
  7. use Doctrine\Common\Collections\ArrayCollection;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use GeoIp2\Database\Reader;
  10. use GeoIp2\Exception\AddressNotFoundException;
  11. use Exception;
  12. use Lustery\Model\Base\Country;
  13. use Lustery\Model\Members\User;
  14. use Lustery\Repository\Base\CountryRepository;
  15.  
  16. class GeoIpUtils
  17. {
  18.     private static $readers;
  19.  
  20.     private $entityManager;
  21.  
  22.     public function __construct(EntityManagerInterface $entityManager)
  23.     {
  24.         $this->entityManager = $entityManager;
  25.     }
  26.  
  27.     /**
  28.      * @param User|null $user
  29.      * @return ArrayCollection<Country>
  30.      */
  31.     public function detectCountry(?User $user): ArrayCollection
  32.     {
  33.         $countryCode = !empty($_COOKIE['country_name']) ? $_COOKIE['country_name'] : '';
  34.         $isInternal = $_SERVER['REMOTE_ADDR'] !== '127.0.0.1';
  35.         $isGoogleBot = strstr(strtolower(@$_SERVER['HTTP_USER_AGENT']), "googlebot");
  36.         $isCdn = strstr(strtolower(@$_SERVER['HTTP_HOST']), "cdn");
  37.  
  38.         if (!$countryCode && $isInternal && !$isGoogleBot && !$isCdn) {
  39.             $countryCode = strtolower(self::countryCodeByIp($_SERVER['REMOTE_ADDR']));
  40.             if ($countryCode) {
  41.                 setcookie('country_name', $countryCode, time()+(365*24*3600), "/", COOKIE_DOMAIN);
  42.             } else {
  43.                 Log::geoIpFail($_SERVER['REMOTE_ADDR']);
  44.             }
  45.         }
  46.  
  47.         /** @var CountryRepository $countryRepository */
  48.         $countryRepository = $this->entityManager->getRepository(Country::class);
  49.         $country = $countryCode ? $countryRepository->findOneBy(['iso2' => $countryCode]) : null;
  50.  
  51.         $countries = new ArrayCollection();
  52.         if ($country) {
  53.             $countries->add($country);
  54.         }
  55.  
  56.         if ($user && $user->getCountry()) {
  57.             $countries->add($user->getCountry());
  58.         }
  59.  
  60.         return $countries;
  61.     }
  62.  
  63.     /**
  64.      * @param User|null $user
  65.      * @param ArrayCollection<Country> $countries
  66.      * @return bool
  67.      */
  68.     public function isUserFromOceania(?User $user, ArrayCollection $countries): bool
  69.     {
  70.         $country = $user && $user->getCountry() ? $user->getCountry() : $countries->first();
  71.         return $country && in_array($country->getIso2(), Country::OCEANIA);
  72.     }
  73.  
  74.     private static function getReader($database_filename)
  75.     {
  76.         if (!isset(self::$readers[$database_filename])) {
  77.             self::$readers[$database_filename] = new Reader($database_filename);
  78.         }
  79.         return self::$readers[$database_filename];
  80.     }
  81.  
  82.     public static function countryCodeByIp($ip): string
  83.     {
  84.         $countryCode = '';
  85.         if (!$ip) {
  86.             return $countryCode;
  87.         }
  88.  
  89.         $config = Config::get("geoip");
  90.         try {
  91.             $filename = $config['db_path']['country'];
  92.             $reader = self::getReader($filename);
  93.             $record = $reader->country($ip);
  94.             $countryCode = strtolower($record->country->isoCode);
  95.         } catch (AddressNotFoundException $e) {
  96.         } catch (Exception $e) {
  97.             trigger_error($e->getMessage());
  98.         }
  99.  
  100.         return $countryCode;
  101.     }
  102. }
  103.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement