Skip to content

Commit 3d90c7e

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.4
Conflicts: user_guide_src/source/database/configuration.rst user_guide_src/source/outgoing/response/028.php
2 parents da02262 + a43018a commit 3d90c7e

File tree

27 files changed

+351
-122
lines changed

27 files changed

+351
-122
lines changed

system/Database/BaseResult.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,10 @@ public function getRowObject(int $n = 0)
356356
/**
357357
* Assigns an item into a particular column slot.
358358
*
359-
* @param mixed $key
360-
* @param mixed $value
359+
* @param array|string $key
360+
* @param array|object|stdClass|null $value
361361
*
362-
* @return mixed
362+
* @return void
363363
*/
364364
public function setRow($key, $value = null)
365365
{
@@ -507,7 +507,7 @@ abstract public function freeResult();
507507
* internally before fetching results to make sure the result set
508508
* starts at zero.
509509
*
510-
* @return mixed
510+
* @return bool
511511
*/
512512
abstract public function dataSeek(int $n = 0);
513513

@@ -516,7 +516,7 @@ abstract public function dataSeek(int $n = 0);
516516
*
517517
* Overridden by driver classes.
518518
*
519-
* @return mixed
519+
* @return array|false|null
520520
*/
521521
abstract protected function fetchAssoc();
522522

system/Database/MySQLi/Result.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function freeResult()
117117
* internally before fetching results to make sure the result set
118118
* starts at zero.
119119
*
120-
* @return mixed
120+
* @return bool
121121
*/
122122
public function dataSeek(int $n = 0)
123123
{
@@ -129,7 +129,7 @@ public function dataSeek(int $n = 0)
129129
*
130130
* Overridden by driver classes.
131131
*
132-
* @return mixed
132+
* @return array|false|null
133133
*/
134134
protected function fetchAssoc()
135135
{

system/Database/OCI8/Result.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public function dataSeek(int $n = 0)
8080
*
8181
* Overridden by driver classes.
8282
*
83-
* @return mixed
83+
* @return array|false
8484
*/
8585
protected function fetchAssoc()
8686
{

system/Database/Postgre/Result.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function freeResult()
8383
* internally before fetching results to make sure the result set
8484
* starts at zero.
8585
*
86-
* @return mixed
86+
* @return bool
8787
*/
8888
public function dataSeek(int $n = 0)
8989
{
@@ -95,7 +95,7 @@ public function dataSeek(int $n = 0)
9595
*
9696
* Overridden by driver classes.
9797
*
98-
* @return mixed
98+
* @return array|false
9999
*/
100100
protected function fetchAssoc()
101101
{

system/Database/ResultInterface.php

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace CodeIgniter\Database;
1313

14+
use stdClass;
15+
1416
/**
1517
* @template TConnection of object|resource
1618
* @template TResult of object|resource
@@ -31,7 +33,7 @@ public function getResult(string $type = 'object'): array;
3133
*
3234
* @param string $className The name of the class to use.
3335
*
34-
* @return mixed
36+
* @return array
3537
*/
3638
public function getCustomResultObject(string $className);
3739

@@ -55,10 +57,11 @@ public function getResultObject(): array;
5557
*
5658
* If row doesn't exist, returns null.
5759
*
58-
* @param mixed $n The index of the results to return
60+
* @param int $n The index of the results to return
5961
* @param string $type The type of result object. 'array', 'object' or class name.
6062
*
61-
* @return mixed
63+
* @return array|object|stdClass|null
64+
* @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : object|null))
6265
*/
6366
public function getRow($n = 0, string $type = 'object');
6467

@@ -67,7 +70,7 @@ public function getRow($n = 0, string $type = 'object');
6770
*
6871
* If row doesn't exists, returns null.
6972
*
70-
* @return mixed
73+
* @return array|null
7174
*/
7275
public function getCustomRowObject(int $n, string $className);
7376

@@ -76,7 +79,7 @@ public function getCustomRowObject(int $n, string $className);
7679
*
7780
* If row doesn't exist, returns null.
7881
*
79-
* @return mixed
82+
* @return array|null
8083
*/
8184
public function getRowArray(int $n = 0);
8285

@@ -85,45 +88,45 @@ public function getRowArray(int $n = 0);
8588
*
8689
* If row doesn't exist, returns null.
8790
*
88-
* @return mixed
91+
* @return object|stdClass|null
8992
*/
9093
public function getRowObject(int $n = 0);
9194

9295
/**
9396
* Assigns an item into a particular column slot.
9497
*
95-
* @param string $key
96-
* @param mixed $value
98+
* @param array|string $key
99+
* @param array|object|stdClass|null $value
97100
*
98-
* @return mixed
101+
* @return void
99102
*/
100103
public function setRow($key, $value = null);
101104

102105
/**
103106
* Returns the "first" row of the current results.
104107
*
105-
* @return mixed
108+
* @return array|object|null
106109
*/
107110
public function getFirstRow(string $type = 'object');
108111

109112
/**
110113
* Returns the "last" row of the current results.
111114
*
112-
* @return mixed
115+
* @return array|object|null
113116
*/
114117
public function getLastRow(string $type = 'object');
115118

116119
/**
117120
* Returns the "next" row of the current results.
118121
*
119-
* @return mixed
122+
* @return array|object|null
120123
*/
121124
public function getNextRow(string $type = 'object');
122125

123126
/**
124127
* Returns the "previous" row of the current results.
125128
*
126-
* @return mixed
129+
* @return array|object|null
127130
*/
128131
public function getPreviousRow(string $type = 'object');
129132

@@ -135,7 +138,7 @@ public function getNumRows(): int;
135138
/**
136139
* Returns an unbuffered row and move the pointer to the next row.
137140
*
138-
* @return mixed
141+
* @return array|object|null
139142
*/
140143
public function getUnbufferedRow(string $type = 'object');
141144

@@ -164,7 +167,7 @@ public function freeResult();
164167
* internally before fetching results to make sure the result set
165168
* starts at zero.
166169
*
167-
* @return mixed
170+
* @return bool
168171
*/
169172
public function dataSeek(int $n = 0);
170173
}

system/Database/SQLSRV/Result.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function freeResult()
117117
* internally before fetching results to make sure the result set
118118
* starts at zero.
119119
*
120-
* @return mixed
120+
* @return bool
121121
*/
122122
public function dataSeek(int $n = 0)
123123
{
@@ -137,7 +137,7 @@ public function dataSeek(int $n = 0)
137137
*
138138
* Overridden by driver classes.
139139
*
140-
* @return mixed
140+
* @return array|false|null
141141
*/
142142
protected function fetchAssoc()
143143
{

system/Database/SQLite3/Result.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function freeResult()
9494
* internally before fetching results to make sure the result set
9595
* starts at zero.
9696
*
97-
* @return mixed
97+
* @return bool
9898
*
9999
* @throws DatabaseException
100100
*/
@@ -112,7 +112,7 @@ public function dataSeek(int $n = 0)
112112
*
113113
* Overridden by driver classes.
114114
*
115-
* @return mixed
115+
* @return array|false
116116
*/
117117
protected function fetchAssoc()
118118
{

system/HTTP/RedirectResponse.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function to(string $uri, ?int $code = null, string $method = 'auto')
5050
*
5151
* @throws HTTPException
5252
*/
53-
public function route(string $route, array $params = [], int $code = 302, string $method = 'auto')
53+
public function route(string $route, array $params = [], ?int $code = null, string $method = 'auto')
5454
{
5555
$namedRoute = $route;
5656

system/HTTP/ResponseTrait.php

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -494,29 +494,41 @@ public function sendBody()
494494
/**
495495
* Perform a redirect to a new URL, in two flavors: header or location.
496496
*
497-
* @param string $uri The URI to redirect to
498-
* @param int $code The type of redirection, defaults to 302
497+
* @param string $uri The URI to redirect to
498+
* @param int|null $code The type of redirection, defaults to 302
499499
*
500500
* @return $this
501501
*
502502
* @throws HTTPException For invalid status code.
503503
*/
504504
public function redirect(string $uri, string $method = 'auto', ?int $code = null)
505505
{
506-
// Assume 302 status code response; override if needed
507-
if (empty($code)) {
508-
$code = 302;
509-
}
510-
511506
// IIS environment likely? Use 'refresh' for better compatibility
512-
if ($method === 'auto' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) {
507+
if (
508+
$method === 'auto'
509+
&& isset($_SERVER['SERVER_SOFTWARE'])
510+
&& strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false
511+
) {
513512
$method = 'refresh';
513+
} elseif ($method !== 'refresh' && $code === null) {
514+
// override status code for HTTP/1.1 & higher
515+
if (
516+
isset($_SERVER['SERVER_PROTOCOL'], $_SERVER['REQUEST_METHOD'])
517+
&& $this->getProtocolVersion() >= 1.1
518+
) {
519+
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
520+
$code = 302;
521+
} elseif (in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT', 'DELETE'], true)) {
522+
// reference: https://en.wikipedia.org/wiki/Post/Redirect/Get
523+
$code = 303;
524+
} else {
525+
$code = 307;
526+
}
527+
}
514528
}
515529

516-
// override status code for HTTP/1.1 & higher
517-
// reference: http://en.wikipedia.org/wiki/Post/Redirect/Get
518-
if (isset($_SERVER['SERVER_PROTOCOL'], $_SERVER['REQUEST_METHOD']) && $this->getProtocolVersion() >= 1.1 && $method !== 'refresh') {
519-
$code = ($_SERVER['REQUEST_METHOD'] !== 'GET') ? 303 : ($code === 302 ? 307 : $code);
530+
if ($code === null) {
531+
$code = 302;
520532
}
521533

522534
switch ($method) {

tests/system/CodeIgniterTest.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,15 +491,18 @@ public function testRunRedirectionWithURI()
491491
/**
492492
* @see https://github.com/codeigniter4/CodeIgniter4/issues/3041
493493
*/
494-
public function testRunRedirectionWithURINotSet()
494+
public function testRunRedirectionWithGET()
495495
{
496496
$_SERVER['argv'] = ['index.php', 'example'];
497497
$_SERVER['argc'] = 2;
498498

499-
$_SERVER['REQUEST_URI'] = '/example';
499+
$_SERVER['REQUEST_URI'] = '/example';
500+
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
501+
$_SERVER['REQUEST_METHOD'] = 'GET';
500502

501503
// Inject mock router.
502504
$routes = Services::routes();
505+
// addRedirect() sets status code 302 by default.
503506
$routes->addRedirect('example', 'pages/notset');
504507

505508
$router = Services::router($routes, Services::incomingrequest());
@@ -508,11 +511,37 @@ public function testRunRedirectionWithURINotSet()
508511
ob_start();
509512
$this->codeigniter->run();
510513
ob_get_clean();
514+
511515
$response = $this->getPrivateProperty($this->codeigniter, 'response');
512516
$this->assertSame('http://example.com/pages/notset', $response->header('Location')->getValue());
517+
$this->assertSame(302, $response->getStatusCode());
518+
}
519+
520+
public function testRunRedirectionWithGETAndHTTPCode301()
521+
{
522+
$_SERVER['argv'] = ['index.php', 'example'];
523+
$_SERVER['argc'] = 2;
524+
525+
$_SERVER['REQUEST_URI'] = '/example';
526+
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
527+
$_SERVER['REQUEST_METHOD'] = 'GET';
528+
529+
// Inject mock router.
530+
$routes = Services::routes();
531+
$routes->addRedirect('example', 'pages/notset', 301);
532+
533+
$router = Services::router($routes, Services::incomingrequest());
534+
Services::injectMock('router', $router);
535+
536+
ob_start();
537+
$this->codeigniter->run();
538+
ob_get_clean();
539+
540+
$response = $this->getPrivateProperty($this->codeigniter, 'response');
541+
$this->assertSame(301, $response->getStatusCode());
513542
}
514543

515-
public function testRunRedirectionWithHTTPCode303()
544+
public function testRunRedirectionWithPOSTAndHTTPCode301()
516545
{
517546
$_SERVER['argv'] = ['index.php', 'example'];
518547
$_SERVER['argc'] = 2;
@@ -533,7 +562,7 @@ public function testRunRedirectionWithHTTPCode303()
533562
ob_get_clean();
534563

535564
$response = $this->getPrivateProperty($this->codeigniter, 'response');
536-
$this->assertSame(303, $response->getStatusCode());
565+
$this->assertSame(301, $response->getStatusCode());
537566
}
538567

539568
public function testStoresPreviousURL()

0 commit comments

Comments
 (0)