RequestBuilder::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
ccs 8
cts 8
cp 1
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace ocpu\Request;
4
5
use ocpu\Request\Broker\CURL;
6
use ocpu\Request\Broker\CURLBulk;
7
8
class RequestBuilder
9
{
10
    /**@var string */
11
    private $method;
12
    /**@var string */
13
    private $host;
14
    /**@var array */
15
    private $query;
16
    /**@var array */
17
    private $headers;
18
    /**@var bool */
19
    private $secure;
20
    /**@var IRequestBroker */
21
    private $requester;
22
23 9
    public function __construct(string $method, string $host)
24
    {
25 9
        $this->method = $method;
26 9
        $this->host = $host;
27 9
        $this->query = [];
28 9
        $this->headers = [];
29 9
        $this->secure = true;
30 9
        $this->requester = new CURL();
31 9
    }
32
33
    /**
34
     * @param IRequestBroker $requester
35
     * @return RequestBuilder
36
     */
37 4
    public function setRequester(IRequestBroker $requester): RequestBuilder
38
    {
39 4
        $this->requester = $requester;
40 4
        return $this;
41
    }
42
43
    /**
44
     * @param string $host
45
     * @return RequestBuilder
46
     * @SuppressWarnings(PHPMD)
47
     */
48 9
    public static function get(string $host): RequestBuilder
49
    {
50 9
        return new RequestBuilder("GET", $host);
51
    }
52
53
    /**
54
     * @param string $host
55
     * @return RequestBuilder
56
     * @SuppressWarnings(PHPMD)
57
     */
58 1
    public static function post(string $host): RequestBuilder
59
    {
60 1
        return new RequestBuilder("POST", $host);
61
    }
62
63 2
    public static function multi(array $requests, $broker = null): RequestBuilder
64
    {
65 2
        $req = new RequestBuilder("", "");
66 2
        $broker = $broker ?? new CURLBulk();
67 2
        $broker->init();
68 2
        foreach ($requests as $request) {
69 2
            if ($request instanceof RequestBuilder) {
70 2
                $request->preSend();
71 2
                $broker->addRequest($request->requester);
72
            }
73
        }
74 2
        $req->setRequester($broker);
75 2
        return $req;
76
    }
77
78
    /**
79
     * @return string
80
     */
81 1
    public function getMethod(): string
82
    {
83 1
        return $this->method;
84
    }
85
86
    /**
87
     * @return string
88
     */
89 1
    public function getHost(): string
90
    {
91 1
        return $this->host;
92
    }
93
94
    /**
95
     * @return array
96
     */
97 1
    public function getHeaders(): array
98
    {
99 1
        return $this->headers;
100
    }
101
102 1
    public function secure(): RequestBuilder
103
    {
104 1
        $this->secure = true;
105 1
        return $this;
106
    }
107
108 1
    public function unSecure(): RequestBuilder
109
    {
110 1
        $this->secure = false;
111 1
        return $this;
112
    }
113
114 2
    public function setHeader(string $name, string $value): RequestBuilder
115
    {
116 2
        $this->headers[$name] = $value;
117 2
        return $this;
118
    }
119
120 1
    public function setQuery(string $name, ?string $value = null): RequestBuilder
121
    {
122 1
        $this->query[$name] = $value;
123 1
        return $this;
124
    }
125
126 4
    private function preSend()
127
    {
128 4
        $url = $this->buildURL();
129 4
        $headers = [];
130 4
        foreach ($this->headers as $name => $value) {
131 1
            $headers[] = "$name: $value";
132
        }
133
134 4
        $this->requester->init();
135 4
        $this->requester->setUrl($url);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ocpu\Request\IRequestBroker as the method setUrl() does only exist in the following implementations of said interface: ocpu\Request\Broker\CURL.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
136 4
        $this->requester->setOpt(CURLOPT_HEADER, $headers);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ocpu\Request\IRequestBroker as the method setOpt() does only exist in the following implementations of said interface: ocpu\Request\Broker\CURL.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
137 4
    }
138
139 4
    public function send()
140
    {
141 4
        if (!($this->requester instanceof IRequestBrokerMulti)) {
142 2
            $this->preSend();
143
        }
144
145 4
        $res = $this->requester->exec();
146 4
        $this->requester->close();
147
148 4
        return $res;
149
    }
150
151 7
    public function buildURL(): string
152
    {
153 7
        $scheme = $this->secure ? "https://" : "http://";
154 7
        $queryString = "";
155 7
        foreach ($this->query as $name => $value) {
156 1
            $queryString .= rawurlencode($name);
157 1
            if ($value !== null) {
158 1
                $queryString .= "=" . rawurlencode($value) . "&";
159
            }
160
        }
161 7
        $queryString = rtrim($queryString, "&");
162
163 7
        return $scheme . $this->host . (strlen($queryString) > 0 ? "?$queryString" : "");
164
    }
165
166 2
    public function getAsJSON()
167
    {
168 2
        $res = $this->send();
169 2
        if (is_array($res)) {
170 1
            return json_decode("[".implode(",", $res)."]");
171
        }
172 1
        return json_decode($res);
173
    }
174
}
175