Completed
Pull Request — master (#187)
by Sergey
02:14
created

CurlHttpClient::cookie()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace seregazhuk\PinterestBot\Api;
4
5
use seregazhuk\PinterestBot\Helpers\Cookies;
6
use seregazhuk\PinterestBot\Helpers\UrlBuilder;
7
use seregazhuk\PinterestBot\Api\Contracts\HttpClient;
8
9
/**
10
 * Class CurlAdapter.
11
 */
12
class CurlHttpClient implements HttpClient
13
{
14
    /**
15
     * Custom CURL options for requests.
16
     *
17
     * @var array
18
     */
19
    protected $options = [
20
        CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0'
21
    ];
22
23
    /**
24
     * @var array
25
     */
26
    protected $headers = [];
27
28
    /**
29
     * Contains the curl instance.
30
     *
31
     * @var resource
32
     */
33
    protected $curl;
34
35
    /**
36
     * @var string
37
     */
38
    protected $cookieJar;
39
40
    /**
41
     * Cookies container
42
     *
43
     * @var Cookies
44
     */
45
    protected $cookies;
46
47
    /**
48
     * @var string
49
     */
50
    protected $currentUrl;
51
52
    /**
53
     * @var string
54
     */
55
    protected $cookiesPath;
56
57
    public function __construct(Cookies $cookies)
58
    {
59
        $this->cookies = $cookies;
60
    }
61
62
    /**
63
     * Load cookies for specified username
64
     *
65
     * @param string $username
66
     * @return HttpClient
67
     */
68
    public function loadCookies($username = '')
69
    {
70
        return $this->initCookieJar($username)
71
            ->fillCookies();
72
    }
73
74
    /**
75
     * Executes curl request.
76
     *
77
     * @param string $url
78
     * @param string $postString
79
     * @param array $headers
80
     * @return string
81
     */
82
    public function execute($url, $postString = '', array $headers = [])
83
    {
84
        $this->init($url, $postString, $headers);
85
86
        $res = curl_exec($this->curl);
87
        $this->setCurrentUrl();
88
89
        curl_close($this->curl);
90
91
        $this->fillCookies();
92
        return $res;
93
    }
94
95
    /**
96
     * Initializes curl resource with options.
97
     *
98
     * @param string $url
99
     * @param string $postString
100
     * @param array $headers
101
     * @return $this
102
     */
103
    protected function init($url, $postString, $headers)
104
    {
105
        $this->headers = $headers;
106
107
        $this->curl = curl_init($url);
108
109
        if (empty($this->cookieJar)) {
110
            $this->loadCookies();
111
        }
112
113
        curl_setopt_array($this->curl, $this->makeHttpOptions($postString));
114
115
        return $this;
116
    }
117
118
    /**
119
     * @return array
120
     */
121
    protected function getDefaultHttpOptions()
122
    {
123
        return [
124
            CURLOPT_RETURNTRANSFER => true,
125
            CURLOPT_SSL_VERIFYPEER => false,
126
            CURLOPT_FOLLOWLOCATION => true,
127
            CURLOPT_ENCODING       => 'gzip,deflate',
128
            CURLOPT_HTTPHEADER     => $this->headers,
129
            CURLOPT_REFERER        => UrlBuilder::URL_BASE,
130
            CURLOPT_COOKIEFILE     => $this->cookieJar,
131
            CURLOPT_COOKIEJAR      => $this->cookieJar,
132
        ];
133
    }
134
135
    /**
136
     * Adds necessary curl options for query.
137
     *
138
     * @param string $postString POST query string
139
     *
140
     * @return array
141
     */
142
    protected function makeHttpOptions($postString = '')
143
    {
144
        // Union custom Curl options and default.
145
        $options = array_replace(
146
            $this->options,
147
            $this->getDefaultHttpOptions()
148
        );
149
150
        if (!empty($postString)) {
151
            $options[CURLOPT_POST] = true;
152
            $options[CURLOPT_POSTFIELDS] = $postString;
153
        }
154
155
        return $options;
156
    }
157
158
    /**
159
     * Set custom Curl options to override default
160
     *
161
     * @param array $options
162
     * @return CurlHttpClient
163
     */
164
    public function setOptions(array $options)
165
    {
166
        $this->options = $options;
167
168
        return $this;
169
    }
170
171
    /**
172
     * Get a cookie value by name
173
     *
174
     * @param $name
175
     * @return mixed
176
     */
177
    public function cookie($name)
178
    {
179
        return $this->cookies->get($name);
180
    }
181
182
    /**
183
     * Get all cookies
184
     *
185
     * @return array
186
     */
187
    public function cookies()
188
    {
189
        return $this->cookies->all();
190
    }
191
192
    /**
193
     * Set directory to store all cookie files.
194
     * @param string $path
195
     * @return $this
196
     */
197
    public function setCookiesPath($path)
198
    {
199
        $this->cookiesPath = $path;
200
201
        return $this;
202
    }
203
204
    /**
205
     * Init cookie file for a specified username. If username is empty we use
206
     * common cookie file for all sessions. If file does not exist it will
207
     * be created in system temp directory.
208
     *
209
     * @param $username
210
     * @return $this
211
     */
212
    protected function initCookieJar($username = '')
213
    {
214
        $this->cookieJar = $this->initCookieFile($username);
215
216
        return $this;
217
    }
218
219
    /**
220
     * Returns cookie file name by username. If username is empty we use a
221
     * random cookie name, to be sure we have different cookies
222
     * in parallel sessions.
223
     *
224
     * @param string $username
225
     * @return string
226
     */
227
    protected function initCookieFile($username)
228
    {
229
        if(empty($username)) {
230
            return tempnam($this->getCookiesPath(), self::COOKIE_PREFIX);
231
        }
232
233
        $cookieName = self::COOKIE_PREFIX . $username;
234
        $cookieFilePath = $this->getCookiesPath() . DIRECTORY_SEPARATOR . $cookieName;
235
236
        if (!file_exists($cookieFilePath)) {
237
            touch($cookieFilePath);
238
        }
239
240
        return $cookieFilePath;
241
    }
242
243
    /**
244
     * @return string
245
     */
246
    public function getCookiesPath()
247
    {
248
        return $this->cookiesPath ? : sys_get_temp_dir();
249
    }
250
251
    /**
252
     * @return $this
253
     */
254
    protected function fillCookies()
255
    {
256
        $this->cookies->fill($this->cookieJar);
257
258
        return $this;
259
    }
260
261
    /**
262
     * @return string
263
     */
264
    public function getCurrentUrl()
265
    {
266
        return $this->currentUrl;
267
    }
268
269
    protected function setCurrentUrl()
270
    {
271
        $this->currentUrl = curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL);
272
    }
273
}