Completed
Push — master ( 9abbb5...626acb )
by Stefano
02:59
created

HTTP   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 131
rs 10
c 0
b 0
f 0
wmc 29
lcom 1
cbo 2

12 Methods

Rating   Name   Duplication   Size   Complexity  
C request() 0 55 12
A useJSON() 0 3 2
A addHeader() 0 3 1
A removeHeader() 0 3 1
A headers() 0 6 3
A userAgent() 0 3 2
A proxy() 0 3 2
A get() 0 3 1
A post() 0 3 1
A put() 0 3 1
A delete() 0 3 1
A info() 0 21 2
1
<?php
2
3
/**
4
 * HTTP
5
 *
6
 * cURL proxy.
7
 *
8
 * @package core
9
 * @author [email protected]
10
 * @copyright Caffeina srl - 2016 - http://caffeina.com
11
 */
12
13
class HTTP {
14
  use Module, Events;
15
16
  protected static $UA          = "Mozilla/4.0 (compatible; Core::HTTP; Windows NT 6.1)",
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
17
                   $json_data   = false,
18
                   $headers     = [],
19
                   $last_info   = null,
20
                   $proxy       = null; // host:port
21
22
  protected static function request($method, $url, $data=[], array $headers=[], $data_as_json=false, $username=null, $password = null){
23
    $http_method = strtoupper($method);
24
    $ch  = curl_init($url);
25
    $opt = [
26
      CURLOPT_CUSTOMREQUEST   => $http_method,
27
      CURLOPT_SSL_VERIFYHOST  => false,
28
      CURLOPT_CONNECTTIMEOUT  => 10,
29
      CURLOPT_RETURNTRANSFER  => true,
30
      CURLOPT_USERAGENT       => static::$UA,
31
      CURLOPT_HEADER          => false,
32
      CURLOPT_MAXREDIRS       => 10,
33
      CURLOPT_FOLLOWLOCATION  => true,
34
      CURLOPT_ENCODING        => '',
35
      CURLOPT_PROXY           => static::$proxy,
36
    ];
37
38
    if($username && $password) {
39
      $opt[CURLOPT_USERPWD] = "$username:$password";
40
    }
41
42
    $headers = array_merge($headers,static::$headers);
43
44
    if($http_method == 'GET'){
45
        if($data && is_array($data)){
46
          $tmp                       = [];
47
          $queried_url               = $url;
48
          foreach($data as $key=>$val) $tmp[] = $key.'='.$val;
49
          $queried_url               .= (strpos($queried_url,'?') === false) ? '?' : '&';
50
          $queried_url               .= implode('&',$tmp);
51
          $opt[CURLOPT_URL]          = $queried_url;
52
          $opt[CURLOPT_HTTPGET]      = true;
53
          unset($opt[CURLOPT_CUSTOMREQUEST]);
54
        }
55
    } else {
56
        $opt[CURLOPT_CUSTOMREQUEST]  = $http_method;
57
        if($data_as_json or is_object($data)){
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
58
          $headers['Content-Type']   = 'application/json';
59
          $opt[CURLOPT_POSTFIELDS]   = json_encode($data);
60
        } else {
61
          $opt[CURLOPT_POSTFIELDS]   = http_build_query($data);
62
        }
63
    }
64
65
    curl_setopt_array($ch,$opt);
66
    $_harr = [];
67
    foreach($headers as $key=>$val)  $_harr[] = $key.': '.$val;
68
    curl_setopt($ch, CURLOPT_HTTPHEADER, $_harr);
69
    $result = curl_exec($ch);
70
    $contentType = strtolower(curl_getinfo($ch, CURLINFO_CONTENT_TYPE));
71
    static::$last_info = curl_getinfo($ch);
72
    if(false !== strpos($contentType,'json')) $result = json_decode($result);
73
    curl_close($ch);
74
    static::trigger("request", $result, static::$last_info);
75
    return $result;
76
  }
77
78
  public static function useJSON($value=null){
79
    return $value===null ? static::$json_data : static::$json_data = $value;
80
  }
81
82
  public static function addHeader($name,$value){
83
    static::$headers[$name] = $value;
84
  }
85
86
  public static function removeHeader($name){
87
    unset(static::$headers[$name]);
88
  }
89
90
  public static function headers($name=null){
91
    // null === $name ?? static::$headers ?? static::$headers[$name]
92
    return null === $name
93
           ? static::$headers
94
           : ( isset(static::$headers[$name]) ? static::$headers[$name] : '' );
95
  }
96
97
  public static function userAgent($value=null){
98
    return $value===null ? static::$UA : static::$UA = $value;
99
  }
100
101
  public static function proxy($proxy=false){
0 ignored issues
show
Unused Code introduced by
The parameter $proxy is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
102
    return $value===false ? static::$proxy : static::$proxy = $value;
0 ignored issues
show
Bug introduced by
The variable $value does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
103
  }
104
105
  public static function get($url, $data=null, array $headers=[], $username = null, $password = null){
106
    return static::request('get',$url,$data,$headers,false,$username,$password);
107
  }
108
109
  public static function post($url, $data=null, array $headers=[], $username = null, $password = null){
110
    return static::request('post',$url,$data,$headers,static::$json_data,$username,$password);
111
  }
112
113
  public static function put($url, $data=null, array $headers=[], $username = null, $password = null){
114
    return static::request('put',$url,$data,$headers,static::$json_data,$username,$password);
115
  }
116
117
  public static function delete($url, $data=null, array $headers=[], $username = null, $password = null){
118
    return static::request('delete',$url,$data,$headers,static::$json_data,$username,$password);
119
  }
120
121
  public static function info($url = null){
122
    if ($url){
123
      curl_setopt_array($ch = curl_init($url), [
124
        CURLOPT_SSL_VERIFYHOST  => false,
125
        CURLOPT_CONNECTTIMEOUT  => 10,
126
        CURLOPT_RETURNTRANSFER  => true,
127
        CURLOPT_USERAGENT       => static::$UA,
128
        CURLOPT_HEADER          => false,
129
        CURLOPT_ENCODING        => '',
130
        CURLOPT_FILETIME        => true,
131
        CURLOPT_NOBODY          => true,
132
        CURLOPT_PROXY           => static::$proxy,
133
      ]);
134
      curl_exec($ch);
135
      $info = curl_getinfo($ch);
136
      curl_close($ch);
137
      return $info;
138
    } else {
139
      return static::$last_info;
140
    }
141
  }
142
143
}
144
145
class HTTP_Request {
146
  public $method   = 'GET',
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
147
         $url      = null,
148
         $headers  = [],
149
         $body     = '';
150
151
  public function __construct($method, $url, $headers=[], $data=null){
0 ignored issues
show
Unused Code introduced by
The parameter $url is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
152
    $this->method   = strtoupper($method);
153
    $this->url      = new URL($this->url);
154
    $this->headers  = (array)$headers;
155
    if ($data) {
156
      if (isset($this->headers["Content-Type"]) && $this->headers["Content-Type"]=='application/json')
157
        $this->body = json_encode($data);
158
      else
159
        $this->body = http_build_query($data);
160
    }
161
  }
162
163
  public function __toString(){
164
    return "$this->method {$this->url->path}{$this->url->query} HTTP/1.1\r\n"
0 ignored issues
show
Documentation introduced by
The property $path is declared private in URL. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
Documentation introduced by
The property $query is declared private in URL. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
165
          ."Host: {$this->url->host}\r\n"
0 ignored issues
show
Documentation introduced by
The property $host is declared private in URL. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
166
          .($this->headers ? implode("\r\n",$this->headers) . "\r\n" : '')
167
          ."\r\n{$this->body}";
168
  }
169
}
170
171
172
class HTTP_Response {
173
  public $status   = 200,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
174
         $headers  = [],
175
         $contents = '';
176
177
  public function __construct($contents, $status, $headers){
178
    $this->status   = $status;
179
    $this->contents = $contents;
180
    $this->headers  = (array)$headers;
181
  }
182
183
  public function __toString(){
184
    return $this->contents;
185
  }
186
}
187
188