Completed
Pull Request — master (#204)
by Sergey
03:18
created

CurlHttpClient::initCookieFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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