RedirectionIO::findRedirect()   C
last analyzed

Complexity

Conditions 12
Paths 37

Size

Total Lines 54
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 15.0871

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 12
eloc 32
c 7
b 0
f 0
nc 37
nop 0
dl 0
loc 54
rs 6.9666
ccs 26
cts 36
cp 0.7221
crap 15.0871

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
Unused Code introduced by
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
Unused Code introduced by
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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of http_response_code() 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...
134
135
        $this->client->request(new LogCommand($request, $response));
136
    }
137 4
138
    public function exitCode()
139 4
    {
140 4
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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
Bug introduced by
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...
Bug introduced by
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