Completed
Push — master ( 1b44ea...7444a6 )
by Adrian
01:08
created

FactomConnector::heights()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace AdrianMejias\FactomApi;
4
5
class FactomConnector
6
{
7
    /**
8
     * The JSON RPC spec that the API uses.
9
     */
10
    const JSON_RPC = '2.0';
11
    /**
12
     * The "ID" param provided in all requests to the API.
13
     */
14
    const REQUEST_ID = 0;
15
    /**
16
     * The header content type in all requests to the API.
17
     */
18
    const HEADER_CONTENT_TYPE = 'text/plain';
19
    /**
20
     * The generic error if cannot load server properly.
21
     */
22
    const BLANK_PAGE_ERROR = 'Page not found';
23
24
    /**
25
     * The URL for all API requests.
26
     *
27
     * @var null|string
28
     */
29
    protected $url;
30
31
    /**
32
     * Make secure URL requests.
33
     *
34
     * @var null|bool
35
     */
36
    protected $ssl;
37
38
    /**
39
     * Path to the certificate file for using factomd over TLS.
40
     *
41
     * @var null
42
     */
43
    protected $certifcate;
44
45
    /**
46
     * The provided username for interacting with factomd
47
     * Optional.
48
     *
49
     * @var null
50
     */
51
    protected $username;
52
53
    /**
54
     * The provided password for interacting with factomd
55
     * Optional.
56
     *
57
     * @var null
58
     */
59
    protected $password;
60
61
    public function __construct(string $url, bool $ssl = false, string $certificate = null, string $username = null, string $password = null)
62
    {
63
        $this->url = $url;
64
        $this->ssl = $ssl;
65
        $this->certificate = $certificate;
0 ignored issues
show
Bug introduced by
The property certificate does not seem to exist. Did you mean certifcate?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
66
        $this->username = $username;
0 ignored issues
show
Documentation Bug introduced by
It seems like $username can also be of type string. However, the property $username is declared as type null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
67
        $this->password = $password;
0 ignored issues
show
Documentation Bug introduced by
It seems like $password can also be of type string. However, the property $password is declared as type null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
68
69
        if (! function_exists('curl_init')) {
70
            throw InvalidFactomApiConfig::noCurlFound();
71
        } elseif (empty($this->url)) {
72
            throw InvalidFactomApiConfig::noUrlDefined();
73
        } elseif (empty($this->certificate) && $this->ssl) {
0 ignored issues
show
Bug introduced by
The property certificate does not seem to exist. Did you mean certifcate?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
74
            throw InvalidFactomApiConfig::noCertificateDefined();
75
        } elseif (! empty($this->certificate) && $this->ssl) {
0 ignored issues
show
Bug introduced by
The property certificate does not seem to exist. Did you mean certifcate?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
76
            if (preg_match('/^(https:\/\/)/i', $this->url)) {
77
                throw InvalidFactomApiConfig::noSecureUrlDefined();
78
            } elseif (! file_exists($this->certificate)) {
0 ignored issues
show
Bug introduced by
The property certificate does not seem to exist. Did you mean certifcate?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
79
                throw InvalidFactomApiConfig::noCertificateExists();
80
            }
81
        } elseif (! empty($this->username) && empty($this->password)) {
82
            throw InvalidFactomApiConfig::noUsernameDefined();
83
        } elseif (empty($this->username) && ! empty($this->password)) {
84
            throw InvalidFactomApiConfig::noPasswordDefined();
85
        }
86
87
        if (! $this->ssl) {
88
            $this->certificate = null;
0 ignored issues
show
Bug introduced by
The property certificate does not seem to exist. Did you mean certifcate?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
89
        }
90
    }
91
92
    /**
93
     * Initialize the cURL request with all requested params.
94
     *
95
     * @param string $actionName
96
     * @param string $method
97
     * @param array $binaryDataParams
98
     * @param array $customOptions
99
     * @return array
100
     * @throws Exception - ensures we are passing in viable methods
101
     */
102
    private function gatherCurlOptions(string $actionName, string $method, array $binaryDataParams = [], array $customOptions = [])
103
    {
104
        if (! in_array(strtoupper($method), ['GET', 'POST'])) {
105
            throw InvalidFactomApiConfig::invalidMethodCalled();
106
        }
107
108
        $options = [
109
          CURLOPT_HTTPHEADER => [
110
            'Content-Type: '.self::HEADER_CONTENT_TYPE,
111
          ],
112
          CURLOPT_HEADER => false,
113
          CURLOPT_POSTFIELDS => json_encode([
114
            'jsonrpc' => self::JSON_RPC,
115
            'id' => self::REQUEST_ID,
116
            'method' => $actionName,
117
            'params' => $binaryDataParams,
118
          ]),
119
          CURLOPT_SSL_VERIFYHOST => 0,
120
          CURLOPT_SSL_VERIFYPEER => 0,
121
          // CURLOPT_URL => $this->url,
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
122
          CURLOPT_POST => strtoupper($method) == 'POST' ? 1 : 0,
123
          CURLOPT_RETURNTRANSFER => true,
124
          CURLOPT_TIMEOUT => 10,
125
          /*
126
           * Auth related cURL params
127
           */
128
          CURLOPT_USERPWD => ! empty($this->username) && ! empty($this->password) ? $this->username.':'.$this->password : false,
129
          CURLOPT_HTTPAUTH => ! empty($this->username) && ! empty($this->password) ? CURLAUTH_ANY : false,
130
          /*
131
           * Cert / SSL related cURL params
132
           */
133
          CURLOPT_SSL_VERIFYPEER => false,
134
      ] + $customOptions;
135
136
        // return Result
137
        return $options;
138
    }
139
140
    /**
141
     * Call the requested endpoint.
142
     *
143
     * @param string $actionName
144
     * @param array $binaryDataParams
145
     * @param array $curlOptions
146
     *
147
     * @return object|string
148
     *
149
     * @throws Exception When a cURL error occurs
150
     */
151
    public function callEndpoint(string $actionName, string $method, array $binaryDataParams = [], array $curlOptions = [])
152
    {
153
        $curlOptions = $this->gatherCurlOptions($actionName, $method, $binaryDataParams, $curlOptions);
154
155
        $ch = curl_init($this->url);
156
        curl_setopt_array($ch, $curlOptions);
157
        $result = curl_exec($ch);
158
        $error = curl_error($ch);
159
        $info = curl_getinfo($ch);
0 ignored issues
show
Unused Code introduced by
$info is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
160
        curl_close($ch);
161
162
        if (! $error && strtoupper($result) == strtoupper(self::BLANK_PAGE_ERROR)) {
163
            $error = self::BLANK_PAGE_ERROR;
164
        }
165
166
        if ($error) {
167
            throw InvalidFactomApiConfig::invalidApiResponse($error, $actionName);
168
        } elseif (! $result) {
169
            throw InvalidFactomApiConfig::emptyApiResponse($actionName);
170
        }
171
172
        $response = json_decode($result);
173
174
        if (is_object($response) && ! empty($response->result)) {
175
            return $response->result;
176
        }
177
178
        if (is_object($response) && ! empty($response->error)) {
179
            return $response->error;
180
        }
181
182
        // return Result
183
    }
184
}
185