Failed Conditions
Pull Request — dev (#132)
by Steve
02:37
created

src/MageScan/Http.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Mage Scan
4
 *
5
 * PHP version 5
6
 *
7
 * @category  MageScan
8
 * @package   MageScan
9
 * @author    Steve Robbins <[email protected]>
10
 * @copyright 2015 Steve Robbins
11
 * @license   http://creativecommons.org/licenses/by/4.0/ CC BY 4.0
12
 * @link      https://github.com/steverobbins/magescan
13
 */
14
15
namespace MageScan;
16
17
use MageScan\Check\Catalog;
18
use MageScan\Check\Module;
19
use MageScan\Check\Patch;
20
use MageScan\Check\Sitemap;
21
use MageScan\Check\TechHeader;
22
use MageScan\Check\UnreachablePath;
23
use MageScan\Check\Version;
24
use MageScan\Request;
25
use MageScan\Url;
26
27
/**
28
 * Scan a Magento site using a web browser
29
 *
30
 * @category  MageScan
31
 * @package   MageScan
32
 * @author    Steve Robbins <[email protected]>
33
 * @copyright 2015 Steve Robbins
34
 * @license   http://creativecommons.org/licenses/by/4.0/ CC BY 4.0
35
 * @link      https://github.com/steverobbins/magescan
36
 */
37
class Http
38
{
39
    /**
40
     * The URL we are scanning
41
     *
42
     * @var string
43
     */
44
    public $url;
45
46
    /**
47
     * Request object
48
     *
49
     * @var \MageScan\Request
50
     */
51
    protected $request;
52
53
    /**
54
     * Start a check
55
     *
56
     * @param string $code
57
     * @param string $url
58
     */
59
    public function __construct($code, $url)
60
    {
61
        $magescanUrl = new Url;
62
        $this->url     = $magescanUrl->clean(urldecode($url));
63
        $this->request = new Request($this->url, isset($_SERVER['ALLOW_INSECURE']));
64
        call_user_func([$this, 'check' . ucwords($code)]);
65
    }
66
67
    /**
68
     * Check for Magento version
69
     *
70
     * @return void
71
     */
72
    public function checkMagentoinfo()
73
    {
74
        $version = new Version;
75
        $version->setRequest($this->request);
76
        $version = $version->getInfo();
77
        $rows    = [
78
            ['Edition', $version[0] ?: 'Unknown'],
79
            ['Version', $version[1] ?: 'Unknown']
80
        ];
81
        $this->respond(['body' => $rows]);
82
    }
83
84
    /**
85
     * Check for installed modules
86
     *
87
     * @return void
88
     */
89
    public function checkModules()
90
    {
91
        $module = new Module;
92
        $module->setRequest($this->request);
93
        $this->respond(array_keys($module->getFiles()));
94
    }
95
96
    /**
97
     * Check for an installed module
98
     *
99
     * @return void
100
     */
101
    public function checkModulessingle()
102
    {
103
        $module = new Module;
104
        $module->setRequest($this->request);
105
        $file   = $_GET['path'];
106
        $files  = $module->getFiles();
107
        $result = $module->checkForModule($_GET['path']);
108
        if ($result) {
109
            $this->respond([
110
                isset($files[$file]) ? $files[$file] : '<!-- how did this happen -->'
111
            ]);
112
        }
113
    }
114
115
    /**
116
     * Check for install patches
117
     *
118
     * @return void
119
     */
120
    public function checkPatch()
121
    {
122
        $patch   = new Patch;
123
        $patch->setRequest($this->request);
124
        $patches = $patch->checkAll($this->url);
125
        $rows    = [];
126 View Code Duplication
        foreach ($patches as $name => $result) {
127
            switch ($result) {
128
                case PATCH::PATCHED:
129
                    $status = '<span class="pass">Patched</span class="pass">';
130
                    break;
131
                case PATCH::UNPATCHED:
132
                    $status = '<span class="fail">Unpatched</span class="fail">';
133
                    break;
134
                default:
135
                    $status = 'Unknown';
136
            }
137
            $rows[] = [
138
                $name,
139
                $status
140
            ];
141
        }
142
        $this->respond([
143
            'head' => ['Patch', 'Status'],
144
            'body' => $rows
145
        ]);
146
    }
147
148
    /**
149
     * Check for catalog information
150
     *
151
     * @return void
152
     */
153
    public function checkCatalog()
154
    {
155
        $rows    = [];
156
        $catalog = new Catalog;
157
        $catalog->setRequest($this->request);
158
        $categoryCount = $catalog->categoryCount();
159
        $rows[]        = [
160
            '<a href="' . $this->url. 'catalog/seo_sitemap/category" target="_blank">Categories</a>',
161
            $categoryCount !== false ? $categoryCount : 'Unknown'
162
        ];
163
        $productCount = $catalog->productCount();
164
        $rows[]       = [
165
            '<a href="' . $this->url . 'catalog/seo_sitemap/product" target="_blank">Products</a>',
166
            $productCount !== false ? $productCount : 'Unknown'
167
        ];
168
        $this->respond(['body' => $rows]);
169
    }
170
171
    /**
172
     * Check for a valid sitemap
173
     *
174
     * @return void
175
     */
176
    public function checkSitemap()
177
    {
178
        $rows       = [];
179
        $response   = $this->request->get('robots.txt');
0 ignored issues
show
'robots.txt' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
180
        $sitemap    = new Sitemap;
181
        $sitemap->setRequest($this->request);
182
        $sitemapUrl = $sitemap->getSitemapFromRobotsTxt($response);
183
        if ($sitemapUrl === false) {
184
            $rows[] = ['<span class="fail">Sitemap is not declared in <a href="' . $this->url
185
                . 'robots.txt" target="_blank">robots.txt</a></span>'];
186
            $sitemapUrl = $this->url . 'sitemap.xml';
187
        } else {
188
            $rows[] = ['<span class="pass">Sitemap is declared in <a href="' . $this->url
189
                . 'robots.txt" target="_blank">robots.txt</a></span></span>'];
190
        }
191
        $response = $this->request->get($sitemapUrl);
0 ignored issues
show
It seems like $sitemapUrl can also be of type null or string; however, MageScan\Request::get() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
192
        if ($response->code == 200) {
0 ignored issues
show
The property code does not seem to exist in GuzzleHttp\Psr7\Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
193
            $rows[] = ['<span class="pass"><a href="' . $sitemapUrl
194
                . '" target="_blank">Sitemap</a> is accessible</span>'];
195
        } else {
196
            $rows[] = ['<span class="fail"><a href="' . $sitemapUrl
197
                . '" target="_blank">Sitemap</a> is not accessible</span>'];
198
        }
199
        $this->respond(['body' => $rows]);
200
    }
201
202
    /**
203
     * Check for server technologies
204
     *
205
     * @return void
206
     */
207
    public function checkServertech()
208
    {
209
        $rows       = [];
210
        $techHeader = new TechHeader;
211
        $techHeader->setRequest($this->request);
212
        $values     = $techHeader->getHeaders();
213
        if (empty($values)) {
214
            $rows[] = ['No detectable technology was found'];
215
        }
216
        foreach ($values as $key => $value) {
217
            $rows[] = [$key, $value];
218
        }
219
        $this->respond(['body' => $rows]);
220
    }
221
222
    /**
223
     * Check for unreachable paths
224
     *
225
     * @return void
226
     */
227
    public function checkUnreachablepath()
228
    {
229
        $unreachablePath = new UnreachablePath;
230
        $unreachablePath->setRequest($this->request);
231
        $this->respond($unreachablePath->getPaths());
232
    }
233
234
    /**
235
     * Check for unreachable paths
236
     *
237
     * @return void
238
     */
239
    public function checkUnreachablepathsingle()
240
    {
241
        $unreachablePath = new UnreachablePath;
242
        $unreachablePath->setRequest($this->request);
243
        $result          = $unreachablePath->checkPath($_GET['path']);
244
        if ($result[2] === true) {
245
            return;
246
        }
247
        if ($result[2] === false) {
248
            $result[0] = '<a target="_blank" href="' . $this->url . $result[0] . '">' . $result[0] . '</a>';
249
            $result[2] = '<span class="fail">Reachable</span>';
250
        } elseif (substr($result[1], 0, 1) == 3) {
251
            if (substr($result[2], 0, 4) == 'http') {
252
                $newUrl = $result[2];
253
            } else {
254
                $newUrl = $this->url . substr($result[2], 1);
255
            }
256
            $result[0] = '<a target="_blank" href="' . $newUrl . '">' . $result[0] . '</a>';
257
            $result[2] = '<a target="_blank" href="' . $newUrl . '">Redirect</a>';
258
        }
259
        $this->respond($result);
260
    }
261
262
    /**
263
     * Send JSON response
264
     *
265
     * @param array $data
266
     *
267
     * @return void
268
     */
269
    public function respond(array $data)
270
    {
271
        echo json_encode($data);
272
    }
273
}
274