Request   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 114
rs 10
c 0
b 0
f 0
wmc 16

4 Methods

Rating   Name   Duplication   Size   Complexity  
A striposa() 0 9 3
B getBodyParams() 0 40 10
A getContentType() 0 3 1
A getDecryptedBody() 0 10 2
1
<?php declare(strict_types=1);
2
3
namespace yrc\web;
4
5
use yii\base\InvalidConfigException;
6
use yii\web\RequestParserInterface;
7
use yrc\web\Response;
8
use Yii;
9
10
class Request extends \yii\web\Request
11
{
12
    /**
13
     * @var array $parsers
14
     */
15
    public $parsers = [ 
16
        'application/json' => \yii\web\JsonParser::class,
17
        'application/vnd.25519+json' => \yrc\web\ncryptf\JsonParser::class,
18
        'application/vnd.ncryptf+json' => \yrc\web\ncryptf\JsonParser::class,
19
    ];
20
21
    /**
22
     * @var array $_ncryptfContentTypes
23
     */
24
    private $_ncryptfContentTypes = [
25
        'application/vnd.25519+json',
26
        'application/vnd.ncryptf+json'
27
    ];
28
29
    /**
30
     * @var array $_bodyParams
31
     * @see yii\web\Request::_bodyParams
32
     */
33
    private $_bodyParams;
34
35
    /**
36
     * @var string $_decryptedBody
37
     */
38
    private $_decryptedBody;
39
40
    /**
41
     * Returns true if a given need is in an haystack array
42
     * @param array $haystack
43
     * @param string $needle
44
     * @return boolean
45
     */
46
    private function striposa($haystack, $needle)
47
    {
48
        foreach ($haystack as $element) {
49
            if (\stripos($element, $needle) !== false) {
50
                return true;
51
            }
52
        }
53
54
        return false;
55
    }
56
57
    /**
58
     * Returns the decrypted body
59
     * @return string
60
     */
61
    public function getDecryptedBody() :? string
62
    {
63
        $rawContentType = $this->getContentType();
64
65
        if (!$this->striposa($this->_ncryptfContentTypes, $rawContentType)) {
66
            return $this->getRawBody();
67
        }
68
69
        $this->getBodyParams();
70
        return $this->_decryptedBody;
71
    }
72
73
    /**
74
     * @inheritdoc
75
     */
76
    public function getContentType()
77
    {
78
        return parent::getContentType() ?? '';
79
    }
80
81
    /**
82
     * @inheritdoc
83
     */
84
    public function getBodyParams()
85
    {
86
        if ($this->_bodyParams === null) {
87
            if (isset($_POST[$this->methodParam])) {
88
                $this->_bodyParams = $_POST;
89
                unset($this->_bodyParams[$this->methodParam]);
90
                return $this->_bodyParams;
91
            }
92
            $rawContentType = $this->getContentType();
93
            if (($pos = strpos($rawContentType, ';')) !== false) {
94
                // e.g. text/html; charset=UTF-8
95
                $contentType = substr($rawContentType, 0, $pos);
96
            } else {
97
                $contentType = $rawContentType;
98
            }
99
            if (isset($this->parsers[$contentType])) {
100
                $parser = Yii::createObject($this->parsers[$contentType]);
101
                if (!($parser instanceof RequestParserInterface)) {
102
                    throw new InvalidConfigException("The '$contentType' request parser is invalid. It must implement the yii\\web\\RequestParserInterface.");
103
                }
104
                $this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
105
                if ($this->striposa($this->_ncryptfContentTypes, $rawContentType)) {
106
                    $this->_decryptedBody = $parser->getDecryptedBody();
0 ignored issues
show
Bug introduced by
The method getDecryptedBody() does not exist on yii\web\RequestParserInterface. It seems like you code against a sub-type of said class. However, the method does not exist in yii\web\JsonParser. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

106
                    /** @scrutinizer ignore-call */ 
107
                    $this->_decryptedBody = $parser->getDecryptedBody();
Loading history...
107
                }
108
            } elseif (isset($this->parsers['*'])) {
109
                $parser = Yii::createObject($this->parsers['*']);
110
                if (!($parser instanceof RequestParserInterface)) {
111
                    throw new InvalidConfigException('The fallback request parser is invalid. It must implement the yii\\web\\RequestParserInterface.');
112
                }
113
                $this->_bodyParams = $parser->parse($this->getRawBody(), $rawContentType);
114
            } elseif ($this->getMethod() === 'POST') {
115
                // PHP has already parsed the body so we have all params in $_POST
116
                $this->_bodyParams = $_POST;
117
            } else {
118
                $this->_bodyParams = [];
119
                mb_parse_str($this->getRawBody(), $this->_bodyParams);
120
            }
121
        }
122
123
        return $this->_bodyParams;
124
    }
125
}
126