Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
40.00% |
24 / 60 |
|
66.67% |
2 / 3 |
CRAP | |
0.00% |
0 / 1 |
MaxMindCommands | |
40.00% |
24 / 60 |
|
66.67% |
2 / 3 |
13.78 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
downloadCities | |
10.00% |
4 / 40 |
|
0.00% |
0 / 1 |
9.56 | |||
locations | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace Drupal\visitors_geoip\Commands; |
4 | |
5 | use Drupal\Core\Archiver\Tar; |
6 | use Drupal\Core\Config\ConfigFactoryInterface; |
7 | use Drupal\Core\File\FileExists; |
8 | use Drupal\Core\File\FileSystemInterface; |
9 | use Drupal\visitors_geoip\VisitorsGeoIpRebuildLocationInterface; |
10 | use Drush\Commands\DrushCommands; |
11 | use GuzzleHttp\Client; |
12 | use Symfony\Component\Console\Helper\ProgressBar; |
13 | |
14 | /** |
15 | * Defines a Drush command related to MaxMind. |
16 | */ |
17 | class MaxMindCommands extends DrushCommands { |
18 | |
19 | const URL = 'https://download.maxmind.com/app/geoip_download'; |
20 | |
21 | /** |
22 | * The http client. |
23 | * |
24 | * @var \GuzzleHttp\Client |
25 | */ |
26 | protected $client; |
27 | |
28 | /** |
29 | * The geo ip settings. |
30 | * |
31 | * @var \Drupal\Core\Config\ImmutableConfig |
32 | */ |
33 | protected $settings; |
34 | |
35 | /** |
36 | * The file system service. |
37 | * |
38 | * @var \Drupal\Core\File\FileSystemInterface |
39 | */ |
40 | protected $fileSystem; |
41 | |
42 | /** |
43 | * The visitors rebuild location service. |
44 | * |
45 | * @var \Drupal\visitors_geoip\VisitorsGeoIpRebuildLocationInterface |
46 | */ |
47 | protected $location; |
48 | |
49 | /** |
50 | * Drush commands for rebuilding logs. |
51 | * |
52 | * @param \GuzzleHttp\Client $http_client |
53 | * The visitors rebuild route service. |
54 | * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory |
55 | * The state service. |
56 | * @param \Drupal\Core\File\FileSystemInterface $file_system |
57 | * The visitors rebuild ip address service. |
58 | * @param \Drupal\visitors_geoip\VisitorsGeoIpRebuildLocationInterface $location |
59 | * The visitors rebuild location service. |
60 | */ |
61 | public function __construct( |
62 | Client $http_client, |
63 | ConfigFactoryInterface $config_factory, |
64 | FileSystemInterface $file_system, |
65 | VisitorsGeoIpRebuildLocationInterface $location, |
66 | ) { |
67 | parent::__construct(); |
68 | |
69 | $this->client = $http_client; |
70 | $this->settings = $config_factory->get('visitors_geoip.settings'); |
71 | $this->fileSystem = $file_system; |
72 | $this->location = $location; |
73 | } |
74 | |
75 | /** |
76 | * Regenerates routes from path. |
77 | * |
78 | * @command visitors:download:city |
79 | * @aliases visitors-download-city |
80 | * |
81 | * @usage drush visitors:download:city |
82 | * Generates routes from the visitors_path. |
83 | */ |
84 | public function downloadCities() { |
85 | $license = $this->settings->get('license'); |
86 | if (empty($license)) { |
87 | $this->output()->writeln('You must set a MaxMind license key in the visitors_geoip settings.'); |
88 | return; |
89 | } |
90 | |
91 | $temp_file = $this->fileSystem->tempnam('temporary://', 'geolite2_city_'); |
92 | $real_file = $this->fileSystem->realpath($temp_file); |
93 | |
94 | $geoip_path = $this->settings->get('geoip_path'); |
95 | $path = $this->fileSystem->dirname($geoip_path); |
96 | $path = $this->fileSystem->realpath($path); |
97 | $temp_path = $this->fileSystem->realpath('temporary://'); |
98 | |
99 | // Get the Symfony Console output interface. |
100 | $output = $this->output(); |
101 | // $output->writeLn("There are $total ip addresses to process."); |
102 | $progress_bar = new ProgressBar($output); |
103 | $progress_bar->setFormat('debug'); |
104 | $progress_bar->start(); |
105 | // Initiate the request to download the file. |
106 | $this->client->get( |
107 | self::URL, |
108 | [ |
109 | 'query' => [ |
110 | 'edition_id' => 'GeoLite2-City', |
111 | 'license_key' => $license, |
112 | 'suffix' => 'tar.gz', |
113 | ], |
114 | 'sink' => $real_file, |
115 | 'progress' => function ($curl, $download_total, $downloaded_bytes) use ($progress_bar) { |
116 | $progress_bar->setMaxSteps($download_total); |
117 | $progress_bar->setProgress($downloaded_bytes); |
118 | }, |
119 | ]); |
120 | |
121 | // Finish the progress bar. |
122 | $progress_bar->finish(); |
123 | // Add a new line after the progress bar. |
124 | $output->writeln(''); |
125 | |
126 | $tar = new Tar($real_file, ['compress' => 'gz']); |
127 | $content = $tar->listContents(); |
128 | $matches = preg_grep('/\.mmdb$/', $content); |
129 | $database = reset($matches); |
130 | |
131 | $tar->extract($temp_path, [$database]); |
132 | $db = end(explode('/', $database)); |
133 | if (version_compare(\Drupal::VERSION, '10.3.0', '>=')) { |
134 | $this->fileSystem->copy($temp_path . '/' . $database, $path . '/' . $db, FileExists::Replace); |
135 | } |
136 | else { |
137 | // @phpstan-ignore-next-line |
138 | $this->fileSystem->copy($temp_path . '/' . $database, $path . '/' . $db, FileSystemInterface::EXISTS_REPLACE); |
139 | } |
140 | |
141 | // Output a completion message. |
142 | $output->writeln('Download completed!'); |
143 | } |
144 | |
145 | /** |
146 | * Regenerates location from ip address. |
147 | * |
148 | * @command visitors:rebuild:location |
149 | * @aliases visitors-rebuild-location |
150 | * |
151 | * @usage drush visitors:rebuild:location |
152 | * Generates location from the visitors_ip. |
153 | */ |
154 | public function locations() { |
155 | |
156 | $records = $this->location->getLocations(); |
157 | $total = count($records); |
158 | |
159 | // Get the Symfony Console output interface. |
160 | $output = $this->output(); |
161 | $output->writeLn("There are $total locations to process."); |
162 | $progress_bar = new ProgressBar($output, $total); |
163 | $progress_bar->setFormat('debug'); |
164 | $progress_bar->start(); |
165 | |
166 | do { |
167 | $progress_bar->advance(); |
168 | $record = array_pop($records); |
169 | if (empty($record)) { |
170 | continue; |
171 | } |
172 | |
173 | $this->location->rebuild($record); |
174 | |
175 | } while (count($records)); |
176 | |
177 | // Finish the progress bar. |
178 | $progress_bar->finish(); |
179 | // Add a new line after the progress bar. |
180 | $output->writeln(''); |
181 | |
182 | // Output a completion message. |
183 | $output->writeln('Task completed!'); |
184 | } |
185 | |
186 | } |