Completed
Pull Request — master (#86)
by
unknown
01:32
created

AbstractClient::getConfigDefaultBool()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 3
1
<?php
2
3
namespace AfriCC\EPP;
4
5
use AfriCC\EPP\Frame\Command\Login as LoginCommand;
6
use AfriCC\EPP\Frame\Response as ResponseFrame;
7
use AfriCC\EPP\Frame\ResponseFactory;
8
use Exception;
9
10
/**
11
 * An abstract client client for the Extensible Provisioning Protocol (EPP)
12
 *
13
 * Extend this class in your custom EPP Client
14
 *
15
 * @see http://tools.ietf.org/html/rfc5734
16
 * @see ClientInterface
17
 *
18
 * As this class is abstract and relies on subclass implementation details it's untestable
19
 * @codeCoverageIgnore
20
 */
21
abstract class AbstractClient implements ClientInterface
22
{
23
    protected $host;
24
    protected $port;
25
    protected $username;
26
    protected $password;
27
    protected $lang;
28
    protected $version;
29
    protected $services;
30
    protected $serviceExtensions;
31
    protected $ssl;
32
    protected $local_cert;
33
    protected $ca_cert;
34
    protected $pk_cert;
35
    protected $passphrase;
36
    protected $debug;
37
    protected $connect_timeout;
38
    protected $timeout;
39
    protected $objectSpec;
40
41
    /**
42
     * {@inheritdoc}
43
     *
44
     * @see \AfriCC\EPP\ClientInterface::connect()
45
     */
46
    abstract public function connect($newPassword = false);
47
48
    abstract public function close();
49
50
    abstract protected function log($message);
51
52
    /**
53
     * Send frame to EPP server
54
     *
55
     * @param FrameInterface $frame Frame to send
56
     *
57
     * @throws Exception on send error
58
     */
59
    abstract public function sendFrame(FrameInterface $frame);
60
61
    /**
62
     * Get response frame from EPP server (use after sendFrame)
63
     *
64
     * @throws Exception on frame receive error
65
     *
66
     * @return string raw XML of EPP Frame
67
     */
68
    abstract public function getFrame();
69
70
    public function request(FrameInterface $frame)
71
    {
72
        if ($frame instanceof TransactionAwareInterface) {
73
            $frame->setClientTransactionId(
74
                $this->generateClientTransactionId()
75
                );
76
        }
77
78
        $this->sendFrame($frame);
79
80
        $return = $this->getFrame();
81
82
        return ResponseFactory::build($return, $this->objectSpec);
83
    }
84
85
    public function __construct(array $config, ObjectSpec $objectSpec = null)
86
    {
87
        if (!empty($config['debug']) && is_bool($config['debug'])) {
88
            $this->debug = $config['debug'];
89
        } else {
90
            $this->debug = false;
91
        }
92
93
        if (is_null($objectSpec)) {
94
            $objectSpec = new ObjectSpec();
95
        }
96
97
        $this->objectSpec = $objectSpec;
98
99
        $this->prepareConnectionOptions($config);
100
        $this->prepareCredentials($config);
101
        $this->prepareSSLOptions($config);
102
        $this->prepareEPPServices($config);
103
        $this->prepareEPPVersionLang($lang);
0 ignored issues
show
Bug introduced by
The variable $lang 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...
104
    }
105
106
    /**
107
     * Get client's ObjectSpec
108
     *
109
     * @return ObjectSpec
110
     */
111
    public function getObjectSpec()
112
    {
113
        return $this->objectSpec;
114
    }
115
116
    /**
117
     * Set client's ObjectSpec
118
     *
119
     * @param ObjectSpec $newObjectSpec
120
     */
121
    public function setObjectSpec(ObjectSpec $newObjectSpec)
122
    {
123
        $this->objectSpec = $newObjectSpec;
124
    }
125
126
    /**
127
     * Get config value from config array if set (default otherwise)
128
     *
129
     * Basically, a simple null coallesce operator (since we need to support PHP 5.5)
130
     *
131
     * @param array $config
132
     * @param string $key
133
     * @param mixed $default
134
     * @return mixed
135
     */
136
    protected function getConfigDefault(array $config, string $key, $default = null)
137
    {
138
        if (!empty($config[$key])) {
139
            return $config[$key];
140
        }
141
        return $default;
142
    }
143
144
    /**
145
     * Get config value from config array if set (default otherwise)
146
     *
147
     * special version for bool values
148
     *
149
     * @param array $config
150
     * @param string $key
151
     * @param mixed $default
152
     * @return mixed
153
     * @see AbstractClient::getConfigDefault
154
     */
155
    protected function getConfigDefaultBool(array $config, string $key, $default = null)
156
    {
157
        if (!empty($config[$key]) && is_bool($config[$key])) {
158
            return $config[$key];
159
        }
160
        return $default;
161
    }
162
163
    /**
164
     * Get config value from config array if set (default otherwise)
165
     *
166
     * special version for aray values
167
     *
168
     * @param array $config
169
     * @param string $key
170
     * @param mixed $default
171
     * @return mixed
172
     * @see AbstractClient::getConfigDefault
173
     */
174
    protected function getConfigDefaultArray(array $config, string $key, $default = null)
175
    {
176
        if (!empty($config[$key]) && is_array($config[$key])) {
177
            return $config[$key];
178
        }
179
        return $default;
180
    }
181
182
    /**
183
     * Get config value from config array if set (default otherwise)
184
     *
185
     * special version for files
186
     *
187
     * @param array $config
188
     * @param string $key
189
     * @param mixed $default
190
     * @return mixed
191
     * @throws Exception in case file is specified but not readable
192
     * @see AbstractClient::getConfigDefault
193
     */
194
    protected function getConfigDefaultReadableFile(array $config, string $key, $default = null)
195
    {
196
        if (!empty($config[$key])) {
197
            $return = (string) $config[$key];
198
199
            if (!is_readable($return)) {
200
                throw new \Exception(sprintf('unable to read %s: %s',$key, $return));
201
            }
202
            return $return;
203
        }
204
        return $default;
205
    }
206
207
    protected function prepareConnectionOptions(array $config)
208
    {
209
        $this->host = $this->getConfigDefault($config, 'host');
210
        $this->port = $this->getConfigDefault($config, 'port', false);
211
        $this->connect_timeout = (int) $this->getConfigDefault($config, 'connect_timeout', 16);
212
        $this->timeout = (int) $this->getConfigDefault($config, 'timeout', 32);
213
    }
214
215
    protected function prepareCredentials(array $config)
216
    {
217
        $this->username = $this->getConfigDefault($config, 'username');
218
        $this->password = $this->getConfigDefault($config, 'password');
219
    }
220
221
    protected function prepareSSLOptions(array $config)
222
    {
223
        $this->ssl = $this->getConfigDefaultBool($config, 'ssl', false);
224
225
        $this->local_cert = $this->getConfigDefaultReadableFile($config, 'local_cert');
226
        $this->ca_cert = $this->getConfigDefaultReadableFile($config, 'ca_cert');
227
        $this->pk_cert = $this->getConfigDefaultReadableFile($config, 'pk_cert');
228
229
        $this->passphrase = $this->getConfigDefault($config, 'passphrase');
230
    }
231
232
    protected function prepareEPPServices(array $config)
233
    {
234
        $this->services = $this->getConfigDefaultArray($config, 'services');
235
        $this->serviceExtensions = $this->getConfigDefaultArray($config, 'serviceExtensions');
236
    }
237
238
    protected function prepareEPPVersionLang(array $config)
239
    {
240
        $this->lang = $this->getConfigDefault($config, 'lang', 'en');
241
        $this->version = $this->getConfigDefault($config, 'version', '1.0');
242
    }
243
244
    protected function generateClientTransactionId()
245
    {
246
        return Random::id(64, $this->username);
247
    }
248
249
    /**
250
     * Generate and send login frame
251
     *
252
     * @param bool|string $newPassword New password to set on login, false if not changing password
253
     *
254
     * @throws \Exception On unsuccessful login
255
     *
256
     * @return \AfriCC\EPP\Frame\Response Login response
257
     */
258
    protected function login($newPassword = false)
259
    {
260
        // send login command
261
        $login = new LoginCommand($this->objectSpec);
262
        $login->setClientId($this->username);
263
        $login->setPassword($this->password);
264
        if ($newPassword) {
265
            $login->setNewPassword($newPassword);
266
        }
267
        $login->setVersion($this->version);
268
        $login->setLanguage($this->lang);
269
270
        if (!empty($this->services) && is_array($this->services)) {
271
            foreach ($this->services as $urn) {
272
                $login->addService($urn);
273
            }
274
275
            if (!empty($this->serviceExtensions) && is_array($this->serviceExtensions)) {
276
                foreach ($this->serviceExtensions as $extension) {
277
                    $login->addServiceExtension($extension);
278
                }
279
            }
280
        }
281
282
        $response = $this->request($login);
283
        unset($login);
284
285
        // check if login was successful
286
        if (!($response instanceof ResponseFrame)) {
287
            throw new \Exception('there was a problem logging onto the EPP server');
288
        } elseif ($response->code() !== 1000) {
289
            throw new \Exception($response->message(), $response->code());
290
        }
291
292
        return $response;
293
    }
294
}
295