Completed
Pull Request — master (#34)
by Ghitu
21:00
created

SocketClient::close()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * Copyright 2014 Fabian Grutschus. All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without modification,
7
 * are permitted provided that the following conditions are met:
8
 *
9
 * 1. Redistributions of source code must retain the above copyright notice, this
10
 *   list of conditions and the following disclaimer.
11
 *
12
 * 2. Redistributions in binary form must reproduce the above copyright notice,
13
 *   this list of conditions and the following disclaimer in the documentation
14
 *   and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 *
27
 * The views and conclusions contained in the software and documentation are those
28
 * of the authors and should not be interpreted as representing official policies,
29
 * either expressed or implied, of the copyright holders.
30
 *
31
 * @author    Fabian Grutschus <[email protected]>
32
 * @copyright 2014 Fabian Grutschus. All rights reserved.
33
 * @license   BSD
34
 * @link      http://github.com/fabiang/xmpp
35
 */
36
37
namespace Updivision\Xmpp\Stream;
38
39
use Updivision\Xmpp\Exception\InvalidArgumentException;
40
use Updivision\Xmpp\Util\ErrorHandler;
41
42
/**
43
 * Stream functions wrapper class.
44
 *
45
 * @package Xmpp\Stream
46
 */
47
class SocketClient
48
{
49
50
    const BUFFER_LENGTH = 4096;
51
52
    /**
53
     * Resource.
54
     *
55
     * @var resource
56
     */
57
    protected $resource;
58
59
    /**
60
     * Address.
61
     *
62
     * @var string
63
     */
64
    protected $address;
65
66
    /**
67
     * Constructor takes address as argument.
68
     *
69
     * @param string $address
70
     */
71 6
    public function __construct($address)
72
    {
73 6
        $this->address = $address;
74 6
    }
75
76
    /**
77
     * Connect.
78
     *
79
     * @param integer $timeout    Timeout for connection
80
     * @param boolean $persistent Persitent connection
81
     * @return void
82
     */
83 6
    public function connect($timeout = 30, $persistent = false)
84
    {
85 6
        if (true === $persistent) {
86 3
            $flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT;
87 3
        } else {
88 3
            $flags = STREAM_CLIENT_CONNECT;
89
        }
90
91
        // call stream_socket_client with custom error handler enabled
92 6
        $handler = new ErrorHandler(
93 6
            function ($address, $timeout, $flags) {
94 6
                return stream_socket_client($address, $errno, $errstr, $timeout, $flags);
95 6
            },
96 6
            $this->address,
97 6
            $timeout,
98
            $flags
99 6
        );
100 6
        $resource = $handler->execute(__FILE__, __LINE__);
101
102 6
        stream_set_timeout($resource, $timeout);
103 6
        $this->resource = $resource;
104 6
    }
105
106
    /**
107
     * Reconnect and optionally use different address.
108
     *
109
     * @param string  $address
110
     * @param integer $timeout
111
     * @param bool    $persistent
112
     */
113 3
    public function reconnect($address = null, $timeout = 30, $persistent = false)
114
    {
115 3
        $this->close();
116
117 3
        if (null !== $this->address) {
118 3
            $this->address = $address;
119 3
        }
120
121 3
        $this->connect($timeout, $persistent);
122 3
    }
123
124
    /**
125
     * Close stream.
126
     *
127
     * @return void
128
     */
129 3
    public function close()
130
    {
131 3
        fclose($this->resource);
132 3
    }
133
134
    /**
135
     * Set stream blocking mode.
136
     *
137
     * @param boolean $flag Flag
138
     * @return $this
139
     */
140
    public function setBlocking($flag = true)
141
    {
142
        stream_set_blocking($this->resource, (int) $flag);
143
        return $this;
144
    }
145
146
    /**
147
     * Read from stream.
148
     *
149
     * @param integer $length Bytes to read
150
     * @return string
151
     */
152 3
    public function read($length = self::BUFFER_LENGTH)
153
    {
154 3
        return fread($this->resource, $length);
155
    }
156
157
    /**
158
     * Write to stream.
159
     *
160
     * @param string  $string String
161
     * @param integer $length Limit
162
     * @return void
163
     */
164 3
    public function write($string, $length = null)
165
    {
166 3
        if (null !== $length) {
167 3
            fwrite($this->resource, $string, $length);
168 3
        } else {
169 3
            fwrite($this->resource, $string);
170
        }
171 3
    }
172
173
    /**
174
     * Enable/disable cryptography on stream.
175
     *
176
     * @param boolean $enable     Flag
177
     * @param integer $cryptoType One of the STREAM_CRYPTO_METHOD_* constants.
178
     * @return void
179
     * @throws InvalidArgumentException
180
     */
181
    public function crypto($enable, $cryptoType = null)
182
    {
183
        if (false === $enable) {
184
            $handler = new ErrorHandler('stream_socket_enable_crypto', $this->resource, false);
185
            return $handler->execute(__FILE__, __LINE__);
186
        }
187
188
        if (null === $cryptoType) {
189
            throw new InvalidArgumentException('Second argument is require when enabling crypto an stream');
190
        }
191
192
        return stream_socket_enable_crypto($this->resource, $enable, $cryptoType);
193
    }
194
195
    /**
196
     * Get socket stream.
197
     *
198
     * @return resource
199
     */
200 6
    public function getResource()
201
    {
202 6
        return $this->resource;
203
    }
204
205
    /**
206
     * Return address.
207
     *
208
     * @return string
209
     */
210 3
    public function getAddress()
211
    {
212 3
        return $this->address;
213
    }
214
}
215