Issues (1519)

system/modules/Geography/Geography.php (6 issues)

1
<?php
2
3
/**
4
 * Geography module
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2016 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
class Geography extends Module {
12
13
    public $geographyDbDir = '/tmp/Geography';
14
15
    public function init() {
16
        if (!empty(App::$primary->config['site']['domain'])) {
17
            $domain = App::$primary->config['site']['domain'];
18
        } else {
19
            $domain = implode('.', array_slice(explode('.', idn_to_utf8(INJI_DOMAIN_NAME)), -2));
20
        }
21
        $alias = str_replace($domain, '', idn_to_utf8(INJI_DOMAIN_NAME));
22
        $city = null;
23
        if ($alias) {
24
            $alias = str_replace('.', '', $alias);
25
            $city = Geography\City::get($alias, 'alias');
26
        }
27
        if (!$city) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $city of type null|false is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
28
            if (!file_exists(App::$primary->path . $this->geographyDbDir . '/SxGeoCity.dat')) {
29
                $this->updateDb();
30
            }
31
            if (file_exists(App::$primary->path . $this->geographyDbDir . '/SxGeoCity.dat')) {
32
                $SxGeo = new Geography\SxGeo(App::$primary->path . $this->geographyDbDir . '/SxGeoCity.dat');
33
                $cityIp = $SxGeo->getCity($_SERVER['REMOTE_ADDR']);
34
                if (!empty($cityIp['city']['name_ru'])) {
35
                    $city = Geography\City::get($cityIp['city']['name_ru'], 'name');
36
                }
37
            }
38
        }
39
        if (!empty($_COOKIE['curcity'])) {
40
            $city = \Geography\City::get((int) $_COOKIE['curcity']);
41
        }
42
        if (!$city) {
43
            $city = Geography\City::get(1, 'default');
44
        }
45
        if (!empty($this->config['aliasRedirect']) && $city && $city->alias && !$city->default && !$alias && Module::$cur->name !== 'Exchange1c') {
46
            Tools::redirect('//' . $city->alias . '.' . $domain . $_SERVER['REQUEST_URI']);
0 ignored issues
show
The type Tools 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...
47
        }
48
        Geography\City::$cur = $city;
0 ignored issues
show
Documentation Bug introduced by
It seems like $city can also be of type false. However, the property $cur is declared as type Geography\City. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
49
    }
50
51
    public function updateDb() {
52
        // Обновление файла базы данных Sypex Geo
53
        // Настройки
54
        $url = 'https://sypexgeo.net/files/SxGeoCity_utf8.zip';  // Путь к скачиваемому файлу
55
        $dat_file_dir = App::$primary->path . $this->geographyDbDir; // Каталог в который сохранять dat-файл
56
        $last_updated_file = $dat_file_dir . '/SxGeo.upd'; // Файл в котором хранится дата последнего обновления
57
        $info = false; // Вывод сообщений о работе, true заменить на false после установки в cron
58
59
// Конец настроек
60
61
        set_time_limit(600);
62
//error_reporting(E_ALL);
63
        //header('Content-type: text/plain; charset=utf8');
64
65
        $t = microtime(1);
0 ignored issues
show
The assignment to $t is dead and can be removed.
Loading history...
66
        Tools::createDir($dat_file_dir);
67
        $types = array(
68
            'Country' => 'SxGeo.dat',
69
            'City' => 'SxGeoCity.dat',
70
            'Max' => 'SxGeoMax.dat',
71
        );
72
// Скачиваем архив
73
        preg_match("/(Country|City|Max)/", pathinfo($url, PATHINFO_BASENAME), $m);
74
        $type = $m[1];
75
        $dat_file = $types[$type];
76
        if ($info) echo "Скачиваем архив с сервера\n";
77
78
        $fp = fopen($dat_file_dir . '/SxGeoTmp.zip', 'wb');
79
        $ch = curl_init($url);
80
        curl_setopt_array($ch, array(
81
            CURLOPT_FILE => $fp,
82
            CURLOPT_HTTPHEADER => file_exists($last_updated_file) ? array("If-Modified-Since: " . file_get_contents($last_updated_file)) : array(),
83
        ));
84
        if (!curl_exec($ch)) {
85
            if ($info) echo 'Ошибка при скачивании архива';
86
            return;
87
        }
88
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
89
        curl_close($ch);
90
        fclose($fp);
0 ignored issues
show
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

90
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
91
        if ($code == 304) {
92
            @unlink($dat_file_dir . '/SxGeoTmp.zip');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

92
            /** @scrutinizer ignore-unhandled */ @unlink($dat_file_dir . '/SxGeoTmp.zip');

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
93
            if ($info) echo "Архив не обновился, с момента предыдущего скачивания\n";
94
            return;
95
        }
96
97
        if ($info) echo "Архив с сервера скачан\n";
98
// Распаковываем архив
99
        $fp = fopen('zip://' . $dat_file_dir . '/SxGeoTmp.zip#' . $dat_file, 'rb');
100
        $fw = fopen($dat_file_dir . '/' . $dat_file, 'wb');
101
        if (!$fp) {
102
            if ($info)
103
                echo "Не получается открыть\n";
104
            return;
105
        }
106
        if ($info) echo "Распаковываем архив\n";
107
        stream_copy_to_stream($fp, $fw);
108
        fclose($fp);
109
        fclose($fw);
110
        if (filesize($dat_file) == 0) {
111
            if ($info) echo 'Ошибка при распаковке архива';
112
        }
113
        @unlink($dat_file_dir . '/SxGeoTmp.zip');
114
        file_put_contents($last_updated_file, gmdate('D, d M Y H:i:s') . ' GMT');
115
        if ($info) echo "Перемещен файл в {$dat_file_dir}/{$dat_file}\n";
116
117
    }
118
119
}
120