Passed
Push — master ( c6bcc8...1762a2 )
by Denis
03:27
created

ParseCityAddressRu::generateFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 0
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Ngtfkx\Laradeck\AddressGenerator\Commands;
4
5
use Illuminate\Console\Command;
1 ignored issue
show
Bug introduced by
The type Illuminate\Console\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Facades\Storage;
8
use Symfony\Component\DomCrawler\Crawler;
1 ignored issue
show
Bug introduced by
The type Symfony\Component\DomCrawler\Crawler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
/**
11
 * Парсер улиц и домов с сайта www.city-address.ru
12
 *
13
 * Class ParseCityAddressRu
14
 * @package Ngtfkx\Laradeck\AddressGenerator\Commands
15
 */
16
class ParseCityAddressRu extends Command
17
{
18
    /**
19
     * The name and signature of the console command.
20
     *
21
     * @var string
22
     */
23
    protected $signature = 'address:city-address-ru {city} {url} {--limit=0}';
24
25
    /**
26
     * The console command description.
27
     *
28
     * @var string
29
     */
30
    protected $description = 'Parse streets and building numbers from www.city-address.ru';
31
32
    /**
33
     * @var Collection
34
     */
35
    protected $streets;
36
37
    /**
38
     * @var int
39
     */
40
    protected $cityId;
41
42
    /**
43
     * @var int
44
     */
45
    protected $limit;
46
47
    /**
48
     * @var string
49
     */
50
    protected $url;
51
52
    public function __construct()
53
    {
54
        $this->streets = new Collection();
55
56
        parent::__construct();
57
    }
58
59
    public function handle(): void
60
    {
61
        $this->cityId = $this->argument('city');
62
63
        $this->url = $this->argument('url');
64
65
        $this->limit = (int)$this->option('limit');
66
67
        $this->parse();
68
69
        $this->generateFile();
70
71
        $this->info('Data was saved');
72
    }
73
74
    /**
75
     * Парсинг данных
76
     */
77
    protected function parse(): void
78
    {
79
        /**
80
         * Получаем список всех страниц с улицами
81
         */
82
        $firstPage = $this->download($this->url);
83
84
        $allPages = (int)(new Crawler($firstPage))->filter('.uk-pagination > li')->last()->text();
85
86
        $k = 0;
87
        for ($i = 1; $i <= $allPages; $i++) {
88
            /**
89
             * Получам список улиц на текущей странице
90
             */
91
            $page = $this->download($this->url . '/page-' . $i . '/');
92
93
            $this->line('Downloading streets and building numbers from page #' . $i . ' from ' . $allPages);
94
95
            $streets = (new Crawler($page))->filter('.c4 > a');
96
97
            $streets->each(function ($node) {
98
                /**
99
                 * Получаем список домов
100
                 */
101
                $url = 'http://www.city-address.ru' . $node->attr('href');
102
103
                $page = $this->download($url);
104
105
                /**
106
                 * Обрабатываем список домов
107
                 */
108
                $numbers = collect((new Crawler($page))->filter('.c6 > div > a')->extract('_text'))
109
                    ->reject(function ($item, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

109
                    ->reject(function ($item, /** @scrutinizer ignore-unused */ $key) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
110
                        return strpos($item, 'дом ') !== 0;
111
                    })->map(function ($item, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

111
                    })->map(function ($item, /** @scrutinizer ignore-unused */ $key) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
112
                        return str_replace('дом № ', '', $item);
113
                    })->toArray();
114
115
                $this->streets->put($node->text(), $numbers);
116
            });
117
118
            if (++$k == $this->limit) {
119
                $this->warn('Interrupted by the limit');
120
                break;
121
            }
122
        }
123
    }
124
125
    /**
126
     * Скачивание страница
127
     *
128
     * @param string $url
129
     * @return string
130
     */
131
    protected function download(string $url): string
132
    {
133
        $content = file_get_contents($url);
134
135
        return $content;
136
    }
137
138
    /**
139
     * Запись данных в файл
140
     */
141
    protected function generateFile(): void
142
    {
143
        $output = '<?php' . PHP_EOL . PHP_EOL;
144
        $output .= 'return [' . PHP_EOL;
145
        foreach ($this->streets as $street => $numbers) {
146
            $glueNumbers = implode('", "', $numbers);
147
            if (!empty($glueNumbers)) {
148
                $output .= '    "' . trim($street, ";") . '" => ["' . $glueNumbers . '"],' . PHP_EOL;
149
            }
150
        }
151
        $output .= '];' . PHP_EOL;
152
153
        Storage::put($this->cityId . '.php', $output);
154
    }
155
}
156