Passed
Push — 0.8.x ( fca16e...a09e23 )
by Alexander
07:28 queued 04:00
created

HttpRequest::createFromRequestFactory()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
nc 3
nop 6
dl 0
loc 19
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Lenevor Framework
5
 *
6
 * LICENSE
7
 *
8
 * This source file is subject to the new BSD license that is bundled
9
 * with this package in the file license.md.
10
 * It is also available through the world-wide-web at this URL:
11
 * https://lenevor.com/license
12
 * If you did not receive a copy of the license and are unable to
13
 * obtain it through the world-wide-web, please send an email
14
 * to [email protected] so we can send you a copy immediately.
15
 *
16
 * @package     Lenevor
17
 * @subpackage  Base
18
 * @link        https://lenevor.com
19
 * @copyright   Copyright (c) 2019 - 2023 Alexander Campo <[email protected]>
20
 * @license     https://opensource.org/licenses/BSD-3-Clause New BSD license or see https://lenevor.com/license or see /license.md
21
 */
22
23
namespace Syscodes\Components\Http\Resources;
24
25
use LogicException;
26
use Syscodes\Components\Support\Str;
27
use Syscodes\Components\Http\Loaders\Inputs;
28
29
/**
30
 * Allows that HTTP request  loading to initialize the system.
31
 */
32
trait HttpRequest
33
{
34
	/**
35
	 * Holds the global active request instance.
36
	 *
37
	 * @var bool $requestURI
38
	 */
39
	protected static $requestURI;
40
41
	/**
42
	 * Get the http method parameter.
43
	 * 
44
	 * @var bool $httpMethodParameterOverride
45
	 */
46
	protected static $httpMethodParameterOverride = false;
47
48
    /**
49
	 * Create a new Syscodes HTTP request from server variables.
50
	 * 
51
	 * @return static
52
	 */
53
	public static function capture(): static
54
	{
55
		static::enabledHttpMethodParameterOverride();
56
		
57
		return static::createFromRequest(static::createFromRequestGlobals());
58
	}
59
60
	/**
61
     * Enables support for the _method request parameter to determine the intended HTTP method.
62
     * 
63
     * @return void
64
     */
65
    public static function enabledHttpMethodParameterOverride(): void
66
    {
67
        self::$httpMethodParameterOverride = true;
68
    }
69
	
70
	/**
71
	 * Checks whether support for the _method request parameter is enabled.
72
	 * 
73
	 * @return bool
74
	 */
75
	public static function getHttpMethodParameterOverride(): bool
76
	{
77
		return self::$httpMethodParameterOverride;
78
	}
79
80
	/**
81
	 * Creates an Syscodes request from of the Request class instance.
82
	 * 
83
	 * @param  \Syscodes\Components\Http\Request  $request
84
	 * 
85
	 * @return static
86
	 */
87
	public static function createFromRequest($request): static
88
	{
89
		$newRequest = (new static)->duplicate(
0 ignored issues
show
Bug introduced by
It seems like duplicate() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

89
		$newRequest = (new static)->/** @scrutinizer ignore-call */ duplicate(
Loading history...
90
			$request->query->all(), $request->request->all(), $request->attributes->all(),
91
			$request->cookies->all(), $request->files->all(), $request->server->all()
92
		);
93
		
94
		$newRequest->headers->replace($request->headers->all());
95
		
96
		$newRequest->content = $request->content;
0 ignored issues
show
Bug Best Practice introduced by
The property $content is declared protected in Syscodes\Components\Http\Request. Since you implement __get, consider adding a @property or @property-read.
Loading history...
97
		
98
		if ($newRequest->isJson()) {
99
			$newRequest->request = $newRequest->json();
100
		}
101
		
102
		return $newRequest;
103
	}
104
105
	/**
106
	 * Creates a new request with value from PHP's super global.
107
	 * 
108
	 * @return static
109
	 */
110
	public static function createFromRequestGlobals(): static
111
	{
112
		$request = static::createFromRequestFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);
113
114
		if (Str::startsWith($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')
115
		    && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'])) {
116
			parse_str($request->getContent(), $data);
0 ignored issues
show
Bug introduced by
It seems like getContent() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

116
			parse_str($request->/** @scrutinizer ignore-call */ getContent(), $data);
Loading history...
117
			$request->request = new Inputs($data);
0 ignored issues
show
Bug Best Practice introduced by
The property request does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
118
		}
119
120
		return $request;
121
	}
122
123
	/**
124
	 * Creates a new request from a factory.
125
	 * 
126
	 * @param  array  $query
127
	 * @param  array  $request
128
	 * @param  array  $attributes
129
	 * @param  array  $cookies
130
	 * @param  array  $files
131
	 * @param  array  $server
132
	 * 
133
	 * @return static
134
	 */
135
	private static function createFromRequestFactory(
136
		array $query = [], 
137
		array $request = [],
138
		array $attributes = [] ,
139
		array $cookies = [], 
140
		array $files = [], 
141
		array $server = []
142
	): static {
143
		if (self::$requestURI) {
144
			$request = (self::$requestURI)($query, $request, [], $cookies, $files, $server);
145
146
			if ( ! $request instanceof self) {
147
				throw new LogicException('The Request active must return an instance of Syscodes\Components\Http\Request');
148
			}
149
150
			return $request;
151
		}
152
153
		return new static($query, $request, $attributes, $cookies, $files, $server);
0 ignored issues
show
Unused Code introduced by
The call to Syscodes\Components\Http...pRequest::__construct() has too many arguments starting with $query. ( Ignorable by Annotation )

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

153
		return /** @scrutinizer ignore-call */ new static($query, $request, $attributes, $cookies, $files, $server);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
154
	}
155
156
	/**
157
	 * Returns the factory request currently being used.
158
	 *
159
	 * @param  \Syscodes\Components\Http\Request|callable|null  $request  
160
	 *
161
	 * @return void
162
	 */
163
	public static function setFactory(?callable $request): void
164
	{
165
		self::$requestURI = $request;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request can also be of type callable. However, the property $requestURI is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
166
	}
167
}