CurlPanel::finalizeRequest()   B
last analyzed

Complexity

Conditions 7
Paths 16

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
nc 16
nop 1
dl 0
loc 36
ccs 25
cts 25
cp 1
crap 7
rs 8.4106
c 0
b 0
f 0
1
<?php
2
/**
3
 * Allows the user to log the performed cURL requests for later viewing.
4
 * Since these cannot be tracked automatically, the panel provides 2 utility functions: `curlStart()` and `curlEnd()`
5
 */
6
7
namespace bedezign\yii2\audit\panels;
8
9
use Yii;
10
use bedezign\yii2\audit\components\panels\DataStoragePanel;
11
use yii\grid\GridViewAsset;
12
use yii\data\ArrayDataProvider;
13
14
/**
15
 * Class CurlPanel
16
 * @package bedezign\yii2\audit\src\panels
17
 */
18
class CurlPanel extends DataStoragePanel
19
{
20
    /**
21
     * @var bool    Enable verbose logging on the cURL handle and store the complete connection log
22
     */
23
    public $log = true;
24
25
    /**
26
     * @var bool    Store the returned headers in text
27
     */
28
    public $headers = true;
29
30
    /**
31
     * @var bool    Store the content of the request. If enabled this will set CURLOPT_RETURNTRANSFER
32
     */
33
    public $content = true;
34
35
    /**
36
     * @var array
37
     */
38
    private $_logHandles = [];
39
40
    /**
41
     * @inheritdoc
42
     */
43 78
    public function init()
44
    {
45 78
        parent::init();
46 78
        $this->module->registerFunction('curlExec', [$this, 'doRequest']);
47 78
        $this->module->registerFunction('curlBegin', [$this, 'trackRequest']);
48 78
        $this->module->registerFunction('curlEnd', [$this, 'finalizeRequest']);
49 78
    }
50
51
    /**
52
     * @inheritdoc
53
     */
54 3
    public function getName()
55
    {
56 3
        return Yii::t('audit', 'cURL');
57
    }
58
59
    /**
60
     * @inheritdoc
61
     */
62 3
    public function getLabel()
63
    {
64 3
        return $this->getName() . ' <small>(' . count($this->data) . ')</small>';
65
    }
66
67
    /**
68
     * @param $handle
69
     * @param null $url
70
     * @param null $postData
71
     * @return mixed
72
     */
73 3
    public function doRequest($handle, $url = null, $postData = null)
74
    {
75 3
        $this->trackRequest($handle, $url, $postData);
76 3
        $result = curl_exec($handle);
77 3
        $this->finalizeRequest($handle);
78 3
        return $result;
79
    }
80
81
    /**
82
     * @param $handle
83
     * @param null $url
84
     * @param null $postData
85
     * @return bool
86
     * @internal param $data
87
     */
88 6
    public function trackRequest($handle, $url = null, $postData = null)
89
    {
90 6
        $id = $this->id($handle);
91
92 6
        $this->data[$id] = [];
93
94 6
        if ($url) {
95 3
            $this->data[$id]['starting_url'] = $url;
96 3
            curl_setopt($handle, CURLOPT_URL, $url);
97 3
        }
98
99
        if ($postData)
100 6
            $this->data[$id]['post'] = $postData;
101
102 6
        if ($this->headers)
103 6
            curl_setopt($handle, CURLOPT_HEADERFUNCTION, [$this, 'captureHeader']);
104
105 6
        if ($this->log) {
106 6
            curl_setopt($handle, CURLOPT_VERBOSE, true);
107 6
            curl_setopt($handle, CURLOPT_STDERR, $this->_logHandles[$id] = fopen('php://temp', 'rw+'));
108 6
        }
109
110 6
        if ($this->content)
111 6
            curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
112
113 6
        return true;
114
    }
115
116
    /**
117
     * @param $handle
118
     * @return bool
119
     */
120 6
    public function finalizeRequest($handle)
121
    {
122 6
        $id = $this->id($handle);
123
124 6
        $info = curl_getinfo($handle);
125 6
        if (is_array($info)) {
126 6
            $info['effective_url'] = $info['url'];
127 6
            unset($info['url']);
128 6
            $this->data[$id] = array_merge($this->data[$id], $info);
129 6
        }
130
131 6
        if ($this->log && isset($this->_logHandles[$id])) {
132 3
            $file = $this->_logHandles[$id];
133 3
            rewind($file);
134 3
            $this->data[$id]['log'] = stream_get_contents($file);
135 3
            fclose($file);
136 3
            unset($this->_logHandles[$id]);
137 3
        }
138
139 6
        if ($this->content)
140 6
            $this->data[$id]['content']= curl_multi_getcontent($handle);
141
142
        // Cleanup empty things
143 6
        $this->data[$id] = array_filter($this->data[$id]);
144
145 6
        $errorNumber = curl_errno($handle);
146 6
        $error       = curl_error($handle);
147 6
        if ($errorNumber || strlen($error)) {
148 3
            $this->data[$id]['error'] = $errorNumber;
149 3
            $this->data[$id]['errorMessage'] = $error;
150
151 3
            return false;
152
        }
153
154 3
        return true;
155
    }
156
157
    /**
158
     * @inheritdoc
159
     */
160 57
    public function save()
161
    {
162 57
        return $this->data ? array_values($this->data) : null;
163
    }
164
165
    /**
166
     * @inheritdoc
167
     */
168 3
    public function getDetail()
169
    {
170 3
        $dataProvider = new ArrayDataProvider();
171 3
        $dataProvider->allModels = $this->data;
172
173 3
        return Yii::$app->view->render('panels/curl/index', [
174 3
            'panel'        => $this,
175 3
            'dataProvider' => $dataProvider,
176 3
        ]);
177
    }
178
179
    /**
180
     * @inheritdoc
181
     */
182 3
    public function registerAssets($view)
183
    {
184 3
        GridViewAsset::register($view);
185 3
    }
186
187
    /**
188
     * @param $handle
189
     * @param $header
190
     * @return int
191
     */
192 3
    public function captureHeader($handle, $header)
193
    {
194 3
        $id = $this->id($handle);
195 3
        if (!isset($this->data[$id]['headers']))
196 3
            $this->data[$id]['headers'] = [];
197
198 3
        $this->data[$id]['headers'][] = $header;
199 3
        return strlen($header);
200
    }
201
202
    /**
203
     * @param $resource
204
     * @return bool|mixed
205
     */
206 9
    protected function id($resource)
207
    {
208 9
        if (!is_resource($resource))
209 9
            return false;
210
211 9
        $parts = explode('#', (string)$resource);
212 9
        return array_pop($parts);
213
    }
214
215
}