Completed
Push — master ( 6381a3...c04238 )
by Sergey
05:43 queued 03:13
created

CurlHttpClient::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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