Passed
Push — master ( 700166...f06841 )
by Benjamin
03:07
created

Request   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 174
Duplicated Lines 9.77 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 32
c 5
b 0
f 0
lcom 1
cbo 0
dl 17
loc 174
rs 9.6

22 Methods

Rating   Name   Duplication   Size   Complexity  
A camelize() 0 4 1
A __set() 9 9 2
A __get() 8 8 2
A __construct() 0 8 1
A setUrl() 0 6 2
A getUrl() 0 4 1
A setPostData() 0 8 2
A getPostData() 0 4 1
A getTime() 0 4 1
A startTimer() 0 4 1
A stopTimer() 0 4 1
A getResult() 0 4 1
A callBack() 0 16 3
A addListener() 0 6 2
A notify() 0 7 2
A setTimeout() 0 7 2
A getHandle() 0 9 2
A setHeaders() 0 5 1
A getHeaders() 0 4 1
A setOptions() 0 4 1
A getOptions() 0 4 1
A getResponse() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: lejla
5
 * Date: 2016.02.09.
6
 * Time: 17:34
7
 */
8
9
namespace CurlX;
10
11
/**
12
 * Class Request
13
 * @package CurlX
14
 *
15
 * @property string $url
16
 * @property array $post
17
 * @property float $time
18
 * @property int $timeout
19
 * @property array $options
20
 * @property array $headers
21
 * @property resource $handle
22
 * @property mixed $response
23
 * @property callable[] $listeners
24
 */
25
class Request implements RequestInterface
26
{
27
    protected $url;
28
    protected $post = [];
29
    protected $startTime;
30
    protected $endTime;
31
    protected $result;
32
    protected $listeners = [];
33
    protected $timeout;
34
    protected $curlHandle;
35
    protected $headers = [];
36
    protected $options = [];
37
    protected $success;
38
    protected $response;
39
40
    private function camelize($str)
41
    {
42
        return str_replace('_', '', ucwords($str, '_'));
43
    }
44
45 View Code Duplication
    public function __set($name, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
46
    {
47
        $c = $this->camelize($name);
48
        $m = "set$c";
49
        if(method_exists($this, $m)) {
50
            return $this->$m($value);
51
        }
52
        else user_error("undefined property $name");
53
    }
54
55 View Code Duplication
    public function __get($name) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
56
        $c = $this->camelize($name);
57
        $m = "get$c";
58
        if(method_exists($this, $m)) {
59
            return $this->$m();
60
        }
61
        else user_error("undefined property $name");
62
    }
63
64
    /**
65
     * Request constructor.
66
     * @param string $url optional url
67
     */
68
    public function __construct($url = null)
69
    {
70
        $this->setUrl($url);
71
72
        // Defaults
73
        $this->options[CURLOPT_RETURNTRANSFER] = true;
74
        $this->options[CURLOPT_NOSIGNAL] = 1;
75
    }
76
77
    public function setUrl($url)
78
    {
79
        if (!filter_var($url, FILTER_VALIDATE_URL) === false) {
80
            $this->url = $url;
81
        }
82
    }
83
84
    public function getUrl()
85
    {
86
        return $this->url;
87
    }
88
89
    public function setPostData(array $postValues)
90
    {
91
        $this->post += $postValues;
92
        $this->options[CURLOPT_POST] = 1;
93
        if(!empty($this->post)) {
94
            $this->options[CURLOPT_POSTFIELDS] = http_build_query($this->post);
95
        }
96
    }
97
98
    public function getPostData()
99
    {
100
        return $this->post;
101
    }
102
103
    public function getTime()
104
    {
105
        return $this->endTime - $this->startTime;
106
    }
107
108
    public function startTimer()
109
    {
110
        $this->startTime = microtime(true);
111
    }
112
113
    public function stopTimer()
114
    {
115
        $this->endTime = microtime(true);
116
    }
117
118
    public function getResult()
119
    {
120
        return $this->result;
121
    }
122
123
    public function callBack($result)
124
    {
125
        $this->stopTimer();
126
        $this->result = $result;
127
128
        $requestInfo = curl_getinfo($this->curlHandle);
129
130
        if(curl_errno($this->curlHandle) !== 0 || intval($requestInfo['http_code']) !== 200) {
131
            $this->success = false;
132
        } else {
133
            $this->success = true;
134
            $this->response = curl_multi_getcontent($this->ch);
0 ignored issues
show
Documentation introduced by
The property ch does not exist on object<CurlX\Request>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
135
        }
136
137
        $this->notify();
138
    }
139
140
    public function addListener(callable $function)
141
    {
142
        if(is_callable($function)) {
143
            $this->listeners += $function;
144
        }
145
    }
146
147
    protected function notify()
148
    {
149
        foreach($this->listeners as $listener)
150
        {
151
           call_user_func($listener, $this);
152
        }
153
    }
154
155
    public function setTimeout($timeout)
156
    {
157
        if ($timeout > 0) {
158
            $this->timeout = $timeout;
159
            $this->options[CURLOPT_TIMEOUT_MS] = $this->timeout;
160
        }
161
    }
162
163
    public function getHandle()
164
    {
165
        if(!isset($this->curlHandle)) {
166
            $this->curlHandle = curl_init($this->url);
167
            curl_setopt_array($this->curlHandle, $this->options);
168
        }
169
170
        return $this->curlHandle;
171
    }
172
173
    function setHeaders(array $headers)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
174
    {
175
        $this->headers += $headers;
176
        $this->options[CURLOPT_HTTPHEADER] = $headers;
177
    }
178
179
    function getHeaders()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
180
    {
181
        return $this->headers;
182
    }
183
184
    function setOptions(array $options)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
185
    {
186
        $this->options += $options;
187
    }
188
189
    function getOptions()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
190
    {
191
        return $this->options;
192
    }
193
194
    function getResponse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
195
    {
196
        return $this->response;
197
    }
198
}