Completed
Push — master ( 59b3e2...6dd6b9 )
by Andrii
15:38
created

Request   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 89
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A send() 0 18 2
A prepareContextOptions() 0 19 2
A convertContextOptions() 0 15 3
A composeHeaderLines() 0 15 4
1
<?php
2
/**
3
 * Tools to use API as ActiveRecord for Yii2
4
 *
5
 * @link      https://github.com/hiqdev/yii2-hiart
6
 * @package   yii2-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\hiart\stream;
12
13
use hiqdev\hiart\AbstractRequest;
14
use hiqdev\hiart\RequestErrorException;
15
use yii\helpers\ArrayHelper;
16
use yii\helpers\Inflector;
17
18
/**
19
 * PHP stream request implementation.
20
 *
21
 * @author Andrii Vasyliev <[email protected]>
22
 */
23
class Request extends AbstractRequest
24
{
25
    protected $responseClass = Response::class;
26
27
    public $defaultOptions = [
28
        'http' => [
29
            'ignore_errors' => true,
30
        ],
31
        'ssl' => [
32
            'verify_peer' => false,
33
        ],
34
    ];
35
36
    public function send($options = [])
37
    {
38
39
        try {
40
            $this->build();
41
            $context = stream_context_create($this->prepareContextOptions($options));
42
            $stream = fopen($this->getFullUri(), 'rb', false, $context);
43
            $responseContent = stream_get_contents($stream);
44
            // see http://php.net/manual/en/reserved.variables.httpresponseheader.php
45
            $responseHeaders = $http_response_header;
46
            fclose($stream);
47
        } catch (\Exception $e) {
48
            $errorInfo = ['request' => $this];
49
            throw new RequestErrorException($e->getMessage(), $errorInfo, $e->getCode(), $e);
50
        }
51
52
        return new $this->responseClass($this, $responseContent, $responseHeaders);
53
    }
54
55
    protected function prepareContextOptions($options)
56
    {
57
        $requestOptions = [
58
            'http' => [
59
                'protocol_version' => $this->version,
60
                'method' => $this->method,
61
                'header' => static::composeHeaderLines($this->headers),
62
            ],
63
        ];
64
65
        if (isset($this->body)) {
66
            $requestOptions['http']['content'] = $this->body;
67
        }
68
69
        $dbOptions = $this->convertContextOptions($this->getDb()->config);
70
        $sendOptions = $this->convertContextOptions($options);
71
72
        return ArrayHelper::merge($this->defaultOptions, $dbOptions, $requestOptions, $sendOptions);
73
    }
74
75
    /**
76
     * Composes stream context options from raw options.
77
     * @param array $options raw options.
78
     * @return array stream context options.
79
     */
80
    protected function convertContextOptions(array $options)
81
    {
82
        $contextOptions = [];
83
        foreach ($options as $key => $value) {
84
            $section = 'http';
85
            if (strpos($key, 'ssl') === 0) {
86
                $section = 'ssl';
87
                $key = substr($key, 3);
88
            }
89
            $key = Inflector::underscore($key);
90
            $contextOptions[$section][$key] = $value;
91
        }
92
93
        return $contextOptions;
94
    }
95
96
    public static function composeHeaderLines($headers)
97
    {
98
        $result = [];
99
        foreach ($headers as $name => $values) {
100
            $name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $name)));
101
            if (is_string($values)) {
102
                $values = [$values];
103
            }
104
            foreach ($values as $value) {
105
                $result[] = "$name: $value";
106
            }
107
        }
108
109
        return $result;
110
    }
111
}
112