zend-blog-3-backend

Форк
0
167 строк · 4.4 Кб
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: morontt
5
 * Date: 13.11.16
6
 * Time: 13:05
7
 */
8

9
namespace App\Service;
10

11
use App\Entity\GeoLocation;
12
use App\Entity\GeoLocationCity;
13
use App\Entity\GeoLocationCountry;
14
use App\Service\IpInfo\IpInfoClientInterface;
15
use App\Service\IpInfo\LocationInfo;
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\ORM\EntityManagerInterface;
18

19
class IpInfo
20
{
21
    /**
22
     * @var EntityManager
23
     */
24
    private $em;
25

26
    private IpInfoClientInterface $ipInfoClient;
27

28
    /**
29
     * @param EntityManagerInterface $em
30
     * @param IpInfoClientInterface $ipInfoClient
31
     */
32
    public function __construct(EntityManagerInterface $em, IpInfoClientInterface $ipInfoClient)
33
    {
34
        $this->em = $em;
35
        $this->ipInfoClient = $ipInfoClient;
36
    }
37

38
    /**
39
     * @param string $ip
40
     *
41
     * @return GeoLocation|null
42
     */
43
    public function getLocationByIp(string $ip)
44
    {
45
        $location = $this->em->getRepository(GeoLocation::class)->findOrCreateByIpAddress($ip);
46
        if ($location && !$location->getCity()) {
47
            $location->increaseCountOfCheck();
48
            $data = $this->getCityInfo($ip);
49
            if ($data) {
50
                $location->setCity($this->getCity($data));
51
            }
52

53
            $this->em->flush();
54
        }
55

56
        return $location;
57
    }
58

59
    /**
60
     * Following RFC 1918, Section 3
61
     *
62
     * 10.0.0.0    - 10.255.255.255  (10/8 prefix)
63
     * 172.16.0.0  - 172.31.255.255  (172.16/12 prefix)
64
     * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
65
     *
66
     * @param string $ip
67
     *
68
     * @return bool
69
     */
70
    public function isPrivateIP(string $ip): bool
71
    {
72
        $ip4 = array_map(function ($b) { return (int)$b; }, explode('.', $ip));
73

74
        return $ip4[0] == 10
75
            || ($ip4[0] == 172 && ($ip4[1] & 0xf0) == 16)
76
            || ($ip4[0] == 192 && $ip4[1] == 168);
77
    }
78

79
    /**
80
     * @param LocationInfo $data
81
     *
82
     * @return GeoLocationCity|null
83
     */
84
    protected function getCity(LocationInfo $data)
85
    {
86
        $city = null;
87
        if (!empty($data->cityName) && !empty($data->regionName)) {
88
            $country = $this->getCountry($data);
89
            if ($country) {
90
                $city = $this->em->getRepository(GeoLocationCity::class)->findOneBy([
91
                    'city' => $data->cityName,
92
                    'region' => $data->regionName,
93
                    'country' => $country->getId(),
94
                ]);
95

96
                if (!$city) {
97
                    $city = new GeoLocationCity();
98
                    $city
99
                        ->setCity($data->cityName)
100
                        ->setRegion($data->regionName)
101
                        ->setLatitude($data->latitude)
102
                        ->setLongitude($data->longitude)
103
                        ->setTimeZone($data->timeZone)
104
                        ->setZip($data->zipCode)
105
                        ->setCountry($country)
106
                    ;
107

108
                    $this->em->persist($city);
109
                    $this->em->flush();
110
                }
111
            }
112
        }
113

114
        return $city;
115
    }
116

117
    /**
118
     * @param LocationInfo $data
119
     *
120
     * @return GeoLocationCountry|null
121
     */
122
    protected function getCountry(LocationInfo $data)
123
    {
124
        $country = null;
125
        if (!empty($data->countryCode) && !empty($data->countryName)) {
126
            $country = $this->em
127
                ->getRepository(GeoLocationCountry::class)
128
                ->findOneByCode($data->countryCode);
129

130
            if (!$country) {
131
                $country = new GeoLocationCountry();
132
                $country
133
                    ->setCode($data->countryCode)
134
                    ->setName($data->countryName)
135
                ;
136

137
                $this->em->persist($country);
138
                $this->em->flush();
139
            }
140
        }
141

142
        return $country;
143
    }
144

145
    /**
146
     * @param $ip
147
     *
148
     * @return LocationInfo|null
149
     */
150
    protected function getCityInfo($ip): ?LocationInfo
151
    {
152
        if (filter_var($ip, FILTER_VALIDATE_IP)) {
153
            if ($this->isPrivateIP($ip)) {
154
                return LocationInfo::createFromArray([
155
                    'countryCode' => '-',
156
                    'countryName' => '-',
157
                    'regionName' => '-',
158
                    'cityName' => '-',
159
                ]);
160
            }
161

162
            return $this->ipInfoClient->getLocationInfo($ip);
163
        }
164

165
        return null;
166
    }
167
}
168

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.