diff --git a/phpstan-baseline.php b/phpstan-baseline.php index 4965de176bee..e8a65036bfc0 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -12133,12 +12133,6 @@ 'count' => 1, 'path' => __DIR__ . '/tests/system/Commands/Translation/LocalizationFinderTest.php', ]; -$ignoreErrors[] = [ - // identifier: missingType.return - 'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\ConfigCheckTest\\:\\:getBuffer\\(\\) has no return type specified\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/tests/system/Commands/Utilities/ConfigCheckTest.php', -]; $ignoreErrors[] = [ // identifier: missingType.return 'message' => '#^Method CodeIgniter\\\\Commands\\\\Utilities\\\\NamespacesTest\\:\\:getBuffer\\(\\) has no return type specified\\.$#', diff --git a/system/Config/Services.php b/system/Config/Services.php index c0d5fcc392d2..61026de4292c 100644 --- a/system/Config/Services.php +++ b/system/Config/Services.php @@ -211,7 +211,7 @@ public static function curlrequest(array $options = [], ?ResponseInterface $resp return new CURLRequest( $config, - new URI($options['base_uri'] ?? null), + new URI($options['baseURI'] ?? null), $response, $options ); diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php index 425b058932de..92c25ab49984 100644 --- a/system/Database/Postgre/Connection.php +++ b/system/Database/Postgre/Connection.php @@ -150,8 +150,9 @@ private function convertDSN() */ public function reconnect() { - if (pg_ping($this->connID) === false) { - $this->connID = false; + if ($this->connID === false || pg_ping($this->connID) === false) { + $this->close(); + $this->initialize(); } } diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index d0dda0ad5752..a6a2b26a71fc 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -356,9 +356,9 @@ public function reportOnly(bool $value = true) } /** - * Adds a new base_uri value. Can be either a URI class or a simple string. + * Adds a new baseURI value. Can be either a URI class or a simple string. * - * base_uri restricts the URLs that can appear in a page's element. + * baseURI restricts the URLs that can appear in a page's element. * * @see http://www.w3.org/TR/CSP/#directive-base-uri * diff --git a/tests/system/Commands/Utilities/ConfigCheckTest.php b/tests/system/Commands/Utilities/ConfigCheckTest.php index c075ac3df422..c69cfa948635 100644 --- a/tests/system/Commands/Utilities/ConfigCheckTest.php +++ b/tests/system/Commands/Utilities/ConfigCheckTest.php @@ -13,9 +13,12 @@ namespace CodeIgniter\Commands\Utilities; +use Closure; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\StreamFilterTrait; use Config\App; +use Kint\Kint; +use Kint\Renderer\CliRenderer; use PHPUnit\Framework\Attributes\Group; /** @@ -26,6 +29,26 @@ final class ConfigCheckTest extends CIUnitTestCase { use StreamFilterTrait; + public static function setUpBeforeClass(): void + { + App::$override = false; + + putenv('NO_COLOR=1'); + CliRenderer::$cli_colors = false; + + parent::setUpBeforeClass(); + } + + public static function tearDownAfterClass(): void + { + App::$override = true; + + putenv('NO_COLOR'); + CliRenderer::$cli_colors = true; + + parent::tearDownAfterClass(); + } + protected function setUp(): void { $this->resetServices(); @@ -38,188 +61,71 @@ protected function tearDown(): void parent::tearDown(); } - protected function getBuffer() - { - return $this->getStreamFilterBuffer(); - } - - public function testCommandConfigCheckNoArg(): void + public function testCommandConfigCheckWithNoArgumentPassed(): void { command('config:check'); - $this->assertStringContainsString( - 'You must specify a Config classname.', - $this->getBuffer() - ); - } - - public function testCommandConfigCheckApp(): void - { - command('config:check App'); + $this->assertSame( + <<<'EOF' + You must specify a Config classname. + Usage: config:check + Example: config:check App + config:check 'CodeIgniter\Shield\Config\Auth' - $this->assertStringContainsString(App::class, $this->getBuffer()); - $this->assertStringContainsString("public 'baseURL", $this->getBuffer()); + EOF, + str_replace("\n\n", "\n", $this->getStreamFilterBuffer()) + ); } public function testCommandConfigCheckNonexistentClass(): void { command('config:check Nonexistent'); - $this->assertStringContainsString( - 'No such Config class: Nonexistent', - $this->getBuffer() + $this->assertSame( + "No such Config class: Nonexistent\n", + $this->getStreamFilterBuffer() ); } - public function testGetKintD(): void + public function testConfigCheckWithKintEnabledUsesKintD(): void { - $command = new ConfigCheck(service('logger'), service('commands')); - $getKintD = $this->getPrivateMethodInvoker($command, 'getKintD'); - - $output = $getKintD(new App()); - - $output = preg_replace( - '/(\033\[[0-9;]+m)|(\035\[[0-9;]+m)/u', - '', - $output + /** @var Closure(object): string $command */ + $command = $this->getPrivateMethodInvoker( + new ConfigCheck(service('logger'), service('commands')), + 'getKintD' ); - $this->assertStringContainsString( - 'Config\App#', - $output - ); - $this->assertStringContainsString( - <<<'EOL' - ( - public 'baseURL' -> string (19) "http://example.com/" - public 'allowedHostnames' -> array (0) [] - public 'indexPage' -> string (9) "index.php" - public 'uriProtocol' -> string (11) "REQUEST_URI" - public 'permittedURIChars' -> string (14) "a-z 0-9~%.:_\-" - public 'defaultLocale' -> string (2) "en" - public 'negotiateLocale' -> boolean false - public 'supportedLocales' -> array (1) [ - 0 => string (2) "en" - ] - public 'appTimezone' -> string (3) "UTC" - public 'charset' -> string (5) "UTF-8" - public 'forceGlobalSecureRequests' -> boolean false - public 'proxyIPs' -> array (0) [] - public 'CSPEnabled' -> boolean false - EOL, - $output + command('config:check App'); + + $this->assertSame( + $command(config('App')) . "\n", + preg_replace('/\s+Config Caching: \S+/', '', $this->getStreamFilterBuffer()) ); } - public function testGetVarDump(): void + public function testConfigCheckWithKintDisabledUsesVarDump(): void { - $command = new ConfigCheck(service('logger'), service('commands')); - $getVarDump = $this->getPrivateMethodInvoker($command, 'getVarDump'); - - $output = $getVarDump(new App()); - - if ( - ini_get('xdebug.mode') - && in_array( - 'develop', - explode(',', ini_get('xdebug.mode')), - true - ) - ) { - // Xdebug force adds colors on xdebug.cli_color=2 - $output = preg_replace( - '/(\033\[[0-9;]+m)|(\035\[[0-9;]+m)/u', - '', - $output - ); + /** @var Closure(object): string $command */ + $command = $this->getPrivateMethodInvoker( + new ConfigCheck(service('logger'), service('commands')), + 'getVarDump' + ); + $clean = static fn (string $input): string => trim(preg_replace( + '/(\033\[[0-9;]+m)|(\035\[[0-9;]+m)/u', + '', + $input + )); - // Xdebug overloads var_dump(). - $this->assertStringContainsString( - 'class Config\App#', - $output - ); - $this->assertStringContainsString( - <<<'EOL' - { - public string $baseURL => - string(19) "http://example.com/" - public array $allowedHostnames => - array(0) { - } - public string $indexPage => - string(9) "index.php" - public string $uriProtocol => - string(11) "REQUEST_URI" - public string $permittedURIChars => - string(14) "a-z 0-9~%.:_\-" - public string $defaultLocale => - string(2) "en" - public bool $negotiateLocale => - bool(false) - public array $supportedLocales => - array(1) { - [0] => - string(2) "en" - } - public string $appTimezone => - string(3) "UTC" - public string $charset => - string(5) "UTF-8" - public bool $forceGlobalSecureRequests => - bool(false) - public array $proxyIPs => - array(0) { - } - public bool $CSPEnabled => - bool(false) - } - EOL, - $output - ); - } else { - // PHP's var_dump(). - $this->assertStringContainsString( - 'object(Config\App)#', - $output - ); - $this->assertStringContainsString( - <<<'EOL' - { - ["baseURL"]=> - string(19) "http://example.com/" - ["allowedHostnames"]=> - array(0) { - } - ["indexPage"]=> - string(9) "index.php" - ["uriProtocol"]=> - string(11) "REQUEST_URI" - ["permittedURIChars"]=> - string(14) "a-z 0-9~%.:_\-" - ["defaultLocale"]=> - string(2) "en" - ["negotiateLocale"]=> - bool(false) - ["supportedLocales"]=> - array(1) { - [0]=> - string(2) "en" - } - ["appTimezone"]=> - string(3) "UTC" - ["charset"]=> - string(5) "UTF-8" - ["forceGlobalSecureRequests"]=> - bool(false) - ["proxyIPs"]=> - array(0) { - } - ["CSPEnabled"]=> - bool(false) - } - EOL, - $output + try { + Kint::$enabled_mode = false; + command('config:check App'); + + $this->assertSame( + $clean($command(config('App'))), + $clean(preg_replace('/\s+Config Caching: \S+/', '', $this->getStreamFilterBuffer())) ); + } finally { + Kint::$enabled_mode = true; } } } diff --git a/tests/system/HTTP/CURLRequestShareOptionsTest.php b/tests/system/HTTP/CURLRequestShareOptionsTest.php index 38612ad03e05..8f6277cf9501 100644 --- a/tests/system/HTTP/CURLRequestShareOptionsTest.php +++ b/tests/system/HTTP/CURLRequestShareOptionsTest.php @@ -30,7 +30,7 @@ final class CURLRequestShareOptionsTest extends CURLRequestTest { protected function getRequest(array $options = []): MockCURLRequest { - $uri = isset($options['base_uri']) ? new URI($options['base_uri']) : new URI(); + $uri = isset($options['baseURI']) ? new URI($options['baseURI']) : new URI(); $app = new App(); $config = new ConfigCURLRequest(); @@ -43,7 +43,7 @@ protected function getRequest(array $options = []): MockCURLRequest public function testHeaderContentLengthNotSharedBetweenRequests(): void { $options = [ - 'base_uri' => 'http://www.foo.com/api/v1/', + 'baseURI' => 'http://www.foo.com/api/v1/', ]; $request = $this->getRequest($options); @@ -61,8 +61,8 @@ public function testHeaderContentLengthNotSharedBetweenRequests(): void public function testBodyIsResetOnSecondRequest(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setBody('name=George'); $request->setOutput('Hi there'); diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php index 32ae20c1b2da..316c111559a7 100644 --- a/tests/system/HTTP/CURLRequestTest.php +++ b/tests/system/HTTP/CURLRequestTest.php @@ -47,7 +47,7 @@ protected function setUp(): void */ protected function getRequest(array $options = []): MockCURLRequest { - $uri = isset($options['base_uri']) ? new URI($options['base_uri']) : new URI(); + $uri = isset($options['baseURI']) ? new URI($options['baseURI']) : new URI(); $app = new App(); $config = new ConfigCURLRequest(); @@ -64,7 +64,7 @@ public function testPrepareURLIgnoresAppConfig(): void { config('App')->baseURL = 'http://example.com/fruit/'; - $request = $this->getRequest(['base_uri' => 'http://example.com/v1/']); + $request = $this->getRequest(['baseURI' => 'http://example.com/v1/']); $method = $this->getPrivateMethodInvoker($request, 'prepareURL'); @@ -76,7 +76,7 @@ public function testPrepareURLIgnoresAppConfig(): void */ public function testGetRemembersBaseURI(): void { - $request = $this->getRequest(['base_uri' => 'http://www.foo.com/api/v1/']); + $request = $this->getRequest(['baseURI' => 'http://www.foo.com/api/v1/']); $request->get('products'); @@ -90,7 +90,7 @@ public function testGetRemembersBaseURI(): void */ public function testGetRemembersBaseURIWithHelperMethod(): void { - $request = Services::curlrequest(['base_uri' => 'http://www.foo.com/api/v1/']); + $request = Services::curlrequest(['baseURI' => 'http://www.foo.com/api/v1/']); $uri = $this->getPrivateProperty($request, 'baseURI'); $this->assertSame('www.foo.com', $uri->getHost()); @@ -157,28 +157,17 @@ public function testOptionsSetsCorrectMethod(): void public function testOptionsBaseURIOption(): void { - $options = ['base_uri' => 'http://www.foo.com/api/v1/']; + $options = ['baseURI' => 'http://www.foo.com/api/v1/']; $request = $this->getRequest($options); $this->assertSame('http://www.foo.com/api/v1/', $request->getBaseURI()->__toString()); } - public function testOptionsBaseURIOverride(): void - { - $options = [ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'baseURI' => 'http://bogus/com', - ]; - $request = $this->getRequest($options); - - $this->assertSame('http://bogus/com', $request->getBaseURI()->__toString()); - } - public function testOptionsHeaders(): void { $options = [ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'headers' => ['fruit' => 'apple'], + 'baseURI' => 'http://www.foo.com/api/v1/', + 'headers' => ['fruit' => 'apple'], ]; $request = $this->getRequest(); $this->assertNull($request->header('fruit')); @@ -195,8 +184,8 @@ public function testOptionsHeadersNotUsingPopulate(): void $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip, deflate, br'; $options = [ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'headers' => [ + 'baseURI' => 'http://www.foo.com/api/v1/', + 'headers' => [ 'Host' => 'www.foo.com', 'Accept-Encoding' => '', ], @@ -233,7 +222,7 @@ public function testDefaultOptionsAreSharedBetweenRequests(): void public function testHeaderContentLengthNotSharedBetweenRequests(): void { $options = [ - 'base_uri' => 'http://www.foo.com/api/v1/', + 'baseURI' => 'http://www.foo.com/api/v1/', ]; $request = $this->getRequest($options); @@ -253,7 +242,7 @@ public function testHeaderContentLengthNotSharedBetweenClients(): void $_SERVER['HTTP_CONTENT_LENGTH'] = '10'; $options = [ - 'base_uri' => 'http://www.foo.com/api/v1/', + 'baseURI' => 'http://www.foo.com/api/v1/', ]; $request = $this->getRequest($options); $request->post('example', [ @@ -730,8 +719,8 @@ public function testAllowRedirectsArray(): void public function testSendWithQuery(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'query' => [ + 'baseURI' => 'http://www.foo.com/api/v1/', + 'query' => [ 'name' => 'Henry', 'd.t' => 'value', ], @@ -747,8 +736,8 @@ public function testSendWithQuery(): void public function testSendWithDelay(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->get('products'); @@ -760,8 +749,8 @@ public function testSendWithDelay(): void public function testSendContinued(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setOutput("HTTP/1.1 100 Continue\x0d\x0a\x0d\x0aHi there"); @@ -775,8 +764,8 @@ public function testSendContinued(): void public function testSendContinuedWithManyHeaders(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $output = "HTTP/1.1 100 Continue @@ -819,8 +808,8 @@ public function testSendContinuedWithManyHeaders(): void public function testSendProxied(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $output = "HTTP/1.1 200 Connection established @@ -834,8 +823,8 @@ public function testSendProxied(): void public function testSendProxiedWithHTTP10(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $output = "HTTP/1.0 200 Connection established @@ -852,7 +841,7 @@ public function testSendProxiedWithHTTP10(): void public function testResponseHeadersWithMultipleRequests(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', + 'baseURI' => 'http://www.foo.com/api/v1/', ]); $output = "HTTP/2.0 200 OK @@ -905,7 +894,7 @@ public function testResponseHeadersWithMultipleRequests(): void public function testResponseHeadersWithMultipleSetCookies(): void { $request = $this->getRequest([ - 'base_uri' => 'https://github.com/', + 'baseURI' => 'https://github.com/', ]); $output = "HTTP/2 200 @@ -937,8 +926,8 @@ public function testResponseHeadersWithMultipleSetCookies(): void public function testSplitResponse(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setOutput("Accept: text/html\x0d\x0a\x0d\x0aHi there"); @@ -949,8 +938,8 @@ public function testSplitResponse(): void public function testApplyBody(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setBody('name=George'); @@ -964,8 +953,8 @@ public function testApplyBody(): void public function testApplyBodyByOptions(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setOutput('Hi there'); @@ -980,8 +969,8 @@ public function testApplyBodyByOptions(): void public function testBodyIsResetOnSecondRequest(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setBody('name=George'); $request->setOutput('Hi there'); @@ -995,8 +984,8 @@ public function testBodyIsResetOnSecondRequest(): void public function testResponseHeaders(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setOutput("HTTP/2.0 234 Ohoh\x0d\x0aAccept: text/html\x0d\x0a\x0d\x0aHi there"); @@ -1009,8 +998,8 @@ public function testResponseHeaders(): void public function testResponseHeadersShortProtocol(): void { $request = $this->getRequest([ - 'base_uri' => 'http://www.foo.com/api/v1/', - 'delay' => 100, + 'baseURI' => 'http://www.foo.com/api/v1/', + 'delay' => 100, ]); $request->setOutput("HTTP/2 235 Ohoh\x0d\x0aAccept: text/html\x0d\x0a\x0d\x0aHi there shortie"); diff --git a/user_guide_src/source/changelogs/v4.5.6.rst b/user_guide_src/source/changelogs/v4.5.6.rst index 1dbaf55f2482..9490e62e4e80 100644 --- a/user_guide_src/source/changelogs/v4.5.6.rst +++ b/user_guide_src/source/changelogs/v4.5.6.rst @@ -41,6 +41,7 @@ Bugs Fixed - **Validation:** Fixed a bug where complex language strings were not properly handled. - **CURLRequest:** Added support for handling proxy responses using HTTP versions other than 1.1. +- **Database:** Fixed a bug that caused ``Postgre\Connection::reconnect()`` method to throw an error when the connection had not yet been established. See the repo's `CHANGELOG.md `_ diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst index 3871ec72a2e1..ed5567372324 100644 --- a/user_guide_src/source/libraries/pagination.rst +++ b/user_guide_src/source/libraries/pagination.rst @@ -149,7 +149,7 @@ the previous section. Specify the segment number to use as the fifth parameter t Please note: ``$segment`` value cannot be greater than the number of URI segments plus 1. -If you in need to show many pagers on one page then additional parameter which will define a group could be helpful: +If you need to show many pagers on one page then the additional parameter which will define a group could be helpful: .. literalinclude:: pagination/007.php @@ -224,7 +224,7 @@ usefulness. It is easiest to demonstrate creating a new view by showing you the setSurroundCount() ------------------ -In the first line, the ``setSurroundCount()`` method specifies than we want to show two links to either side of +In the first line, the ``setSurroundCount()`` method specifies that we want to show two links to either side of the current page link. The only parameter that it accepts is the number of links to show. .. note:: You must call this method first to generate correct pagination links. @@ -274,7 +274,7 @@ In the code presented for the standard pagination structure, the methods `getPre If you want to use the pagination structure where prev and next will be links to the previous and next pages based on the current page, just replace the `getPrevious() & getNext()`_ methods with `getPreviousPage() & getNextPage()`_, and the methods `hasPrevious() & hasNext()`_ by `hasPreviousPage() & hasNextPage()`_ respectively. -See following an example with these changes: +See the following example with these changes: .. literalinclude:: pagination/014.php @@ -325,7 +325,7 @@ links to be displayed. For example, if the set of links to be displayed is somet 3 | 4 | 5 | 6 | 7 -``getFirstPageNumber()`` will return 3 while ``getLastPageNumber()`` will return 7. +``getFirstPageNumber()`` will return 3 while ``getLastPageNumber()`` will return 7. .. note:: To obtain the page numbers of the first and last pages in the entire result set, you can use the following approach: The first page number is always 1, and `getPageCount()`_ can be used to