Issues (9)

src/RedirectionIO.php (4 issues)

1
<?php
2
3
namespace RedirectionIO\Client\Wordpress;
4
5
use RedirectionIO\Client\Sdk\Client;
6
use RedirectionIO\Client\Sdk\Command\LogCommand;
7
use RedirectionIO\Client\Sdk\Command\MatchWithResponseCommand;
8
use RedirectionIO\Client\Sdk\HttpMessage\Request;
9
use RedirectionIO\Client\Sdk\HttpMessage\Response;
10
11
/**
12
 * Main plugin file.
13
 *
14
 * This class is the core logic of the plugin.
15
 */
16
class RedirectionIO
17
{
18
    private $client;
19
20 4
    private $missConfigured = false;
21
22 4
    private $lastRuleId;
23 4
24 4
    public function __construct()
25
    {
26
        add_action('plugins_loaded', [$this, 'findRedirect']);
0 ignored issues
show
The call to RedirectionIO\Client\Wordpress\add_action() has too many arguments starting with 'plugins_loaded'. ( Ignorable by Annotation )

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

26
        /** @scrutinizer ignore-call */ 
27
        add_action('plugins_loaded', [$this, 'findRedirect']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
27
        add_action('template_redirect', [$this, 'log']);
28
    }
29
30
    public function setUp()
31
    {
32
        add_option('redirectionio', [
33
            'projectKey' => '',
34
            'connections' => [
35
                [
36
                    'name' => '',
37
                    'remote_socket' => '',
38
                ],
39 4
            ],
40
            'doNotRedirectAdmin' => true,
41 4
        ]);
42 4
    }
43
44 4
    public function findRedirect()
45
    {
46
        $options = get_option('redirectionio');
0 ignored issues
show
The call to RedirectionIO\Client\Wordpress\get_option() has too many arguments starting with 'redirectionio'. ( Ignorable by Annotation )

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

46
        $options = /** @scrutinizer ignore-call */ get_option('redirectionio');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
47
        $connections = [];
48 4
49 4
        if (false === $options || empty($options['projectKey']) || !isset($options['connections'])) {
50 4
            $this->missConfigured = true;
51
52 4
            return false;
53 4
        }
54
55 4
        foreach ($options['connections'] as $connection) {
56
            $connections[$connection['name']] = $connection['remote_socket'];
57 4
        }
58
59
        $this->client = new Client($options['projectKey'], $connections);
60
        $scheme = 'http';
61 4
62 4
        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
63 4
            $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'];
64 4
        } elseif (!empty($_SERVER['HTTPS'])) {
65 4
            $scheme = 'https';
66
        }
67 4
68
        $request = new Request(
69 4
            $_SERVER['HTTP_HOST'],
70
            $_SERVER['REQUEST_URI'],
71
            $_SERVER['HTTP_USER_AGENT'],
72
            $_SERVER['HTTP_REFERER'],
73 4
            $scheme
74
        );
75 4
76 2
        if ($this->isAdminPage($request) && $options['doNotRedirectAdmin']) {
77
            return false;
78
        }
79 2
80
        $response = $this->client->request(new MatchWithResponseCommand($request));
81
82
        if (null === $response) {
83 2
            return false;
84 1
        }
85 1
86 1
        if (method_exists($response, 'getRuleId')) {
87 1
            $this->lastRuleId = $response->getRuleId();
88
        }
89
90 2
        if ($response->getStatusCode() === 410) {
91 2
            \define('DONOTCACHEPAGE', true); // WP Super Cache and W3 Total Cache recognise this
92
            status_header(410);
93
        } else {
94
            wp_redirect($response->getLocation(), $response->getStatusCode());
95
        }
96
97
        $this->exitCode();
98
    }
99
100
    public function log()
101
    {
102
        if ($this->missConfigured) {
103
            return;
104
        }
105
106
        $scheme = 'http';
107
108
        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
109
            $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'];
110
        } elseif (!empty($_SERVER['HTTPS'])) {
111
            $scheme = 'https';
112
        }
113
114
        $location = null;
115
        $headers = headers_list();
116
117
        foreach ($headers as $header) {
118
            $locationPos = stripos($header, 'Location: ');
119
120
            if ($locationPos !== false) {
121
                $location = substr($header, $locationPos);
122
            }
123
        }
124
125
        $request = new Request(
126
            $_SERVER['HTTP_HOST'],
127
            $_SERVER['REQUEST_URI'],
128
            $_SERVER['HTTP_USER_AGENT'],
129
            $_SERVER['HTTP_REFERER'],
130
            $scheme
131
        );
132
133
        $response = new Response(http_response_code(), $this->lastRuleId, $location);
134
135
        $this->client->request(new LogCommand($request, $response));
136
    }
137 4
138
    public function exitCode()
139 4
    {
140 4
        exit;
141
    }
142 4
143 4
    /**
144
     * Check if the requested page belongs to admin area.
145
     */
146
    private function isAdminPage(Request $request)
147
    {
148
        $adminRoot = str_replace(get_site_url(), '', get_admin_url());
0 ignored issues
show
Are you sure the usage of get_site_url() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Are you sure the usage of get_admin_url() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
149
        $requestPath = substr($request->getPath(), 0, \strlen($adminRoot));
150
151
        if ($adminRoot === $requestPath) {
152
            return true;
153
        }
154
155
        return false;
156
    }
157
}
158