diff --git a/composer.json b/composer.json
index a46df741d51a..b31442f7774e 100644
--- a/composer.json
+++ b/composer.json
@@ -111,10 +111,10 @@
],
"metrics": "utils/vendor/bin/phpmetrics --config=phpmetrics.json",
"phpstan:baseline": "vendor/bin/phpstan analyse --ansi --generate-baseline=phpstan-baseline.php",
- "phpstan:check": "vendor/bin/phpstan analyse --verbose --ansi",
+ "phpstan:check": "vendor/bin/phpstan analyse --verbose --ansi --memory-limit 2G",
"sa": "@analyze",
"style": "@cs-fix",
- "test": "phpunit"
+ "test": "phpunit --no-coverage"
},
"scripts-descriptions": {
"analyze": "Run static analysis",
diff --git a/errors.txt b/errors.txt
new file mode 100644
index 000000000000..f77ec77c0efe
--- /dev/null
+++ b/errors.txt
@@ -0,0 +1,202 @@
+15) CodeIgniter\Files\FileCollectionTest::testResolveDirectorySymlink
+ErrorException: symlink(): Permission denied
+
+E:\www\CodeIgniterProjects\dev\tests\system\Files\FileCollectionTest.php:69
+
+16) CodeIgniter\Files\FileCollectionTest::testResolveFileSymlink
+ErrorException: symlink(): Permission denied
+
+E:\www\CodeIgniterProjects\dev\tests\system\Files\FileCollectionTest.php:89
+
+17) CodeIgniter\HTTP\Files\FileMovingTest::testStore
+ErrorException: mkdir(): No such file or directory
+
+E:\www\CodeIgniterProjects\dev\system\HTTP\Files\UploadedFile.php:181
+E:\www\CodeIgniterProjects\dev\system\HTTP\Files\UploadedFile.php:135
+E:\www\CodeIgniterProjects\dev\system\HTTP\Files\UploadedFile.php:355
+E:\www\CodeIgniterProjects\dev\tests\system\HTTP\Files\FileMovingTest.php:213
+
+18) CodeIgniter\Helpers\FilesystemHelperTest::testGetFilenamesWithSymlinks
+ErrorException: symlink(): Permission denied
+
+E:\www\CodeIgniterProjects\dev\tests\system\Helpers\FilesystemHelperTest.php:408
+
+19) CodeIgniter\Helpers\FilesystemHelperTest::testGetFileNotThereInfo
+TypeError: basename(): Argument #1 ($path) must be of type string, false given
+
+E:\www\CodeIgniterProjects\dev\system\Helpers\filesystem_helper.php:322
+E:\www\CodeIgniterProjects\dev\tests\system\Helpers\FilesystemHelperTest.php:525
+
+20) CodeIgniter\Publisher\PublisherInputTest::testAddUri
+CodeIgniter\HTTP\Exceptions\HTTPException: 60 : SSL certificate problem: unable to get local issuer certificate
+
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:709
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:383
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:152
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:187
+E:\www\CodeIgniterProjects\dev\system\Publisher\Publisher.php:331
+E:\www\CodeIgniterProjects\dev\tests\system\Publisher\PublisherInputTest.php:140
+
+21) CodeIgniter\Publisher\PublisherInputTest::testAddUris
+CodeIgniter\HTTP\Exceptions\HTTPException: 60 : SSL certificate problem: unable to get local issuer certificate
+
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:709
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:383
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:152
+E:\www\CodeIgniterProjects\dev\system\HTTP\CURLRequest.php:187
+E:\www\CodeIgniterProjects\dev\system\Publisher\Publisher.php:331
+E:\www\CodeIgniterProjects\dev\system\Publisher\Publisher.php:312
+E:\www\CodeIgniterProjects\dev\tests\system\Publisher\PublisherInputTest.php:150
+
+22) CodeIgniter\Publisher\PublisherSupportTest::testWipe
+CodeIgniter\Publisher\Exceptions\PublisherException: Destination is not on the allowed list of Publisher directories: "C:/Users/aleksandr/AppData/Local/Temp/2d8bc0469a5a/"
+
+E:\www\CodeIgniterProjects\dev\system\Publisher\Publisher.php:183
+E:\www\CodeIgniterProjects\dev\tests\system\Publisher\PublisherSupportTest.php:166
+
+--
+
+There were 6 failures:
+
+1) CodeIgniter\CodeIgniterTest::testRun404OverrideControllerReturnsResponse
+Failed asserting that '\n
+\n
+\n
+
\n
+ \n
+ Welcome to CodeIgniter 4!\n
+ \n
+ \n
+ \n
+...
+\n
+\n
+\n
+\n
+' [ASCII](length: 17399) contains "Oops" [ASCII](length: 4).
+
+E:\www\CodeIgniterProjects\dev\tests\system\CodeIgniterTest.php:164
+
+2) CodeIgniter\CodeIgniterTest::testRun404OverrideReturnResponse
+Failed asserting that '\n
+\n
+\n
+\n
+ \n
+ Welcome to CodeIgniter 4!\n
+ \n
+ \n
+ \n
+...
+\n
+\n
+\n
+\n
+' [ASCII](length: 17400) contains "Oops" [ASCII](length: 4).
+
+E:\www\CodeIgniterProjects\dev\tests\system\CodeIgniterTest.php:182
+
+3) CodeIgniter\CodeIgniterTest::testRun404OverrideByClosure
+Failed asserting that '\n
+\n
+\n
+\n
+ \n
+ Welcome to CodeIgniter 4!\n
+ \n
+ \n
+ \n
+...
+\n
+\n
+\n
+\n
+' [ASCII](length: 17365) contains "404 Override by Closure." [ASCII](length: 24).
+
+E:\www\CodeIgniterProjects\dev\tests\system\CodeIgniterTest.php:203
+
+4) CodeIgniter\Commands\Database\ShowTableInfoMockIOTest::testDbTableWithInputs
+Failed asserting that '+-----------+----------+----------+----------+----------+------+\n
+| hostname | database | username | DBDriver | DBPrefix | port |\n
++-----------+----------+----------+----------+----------+------+\n
+| 127.0.0.1 | :memory: | | SQLite3 | db_ | 3306 |\n
++-----------+----------+----------+----------+----------+------+\n
+\n
+Here is the list of your database tables:\n
+ [0] db_migrations\n
+ [82] db_user\n
+ [83] db_job\n
+ [84] db_misc\n
+ [85] db_type_test\n
+ [86] db_empty\n
+ [87] db_secondary\n
+ [88] db_stringifypkey\n
+ [89] db_without_auto_increment\n
+ [90] db_ip_table\n
+ [92] db_foo\n
+\n
+Which table do you want to see? [0, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92]: a\n
+The "Which table do you want to see?" field must be one of: 0, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92.\n
+\n
+Which table do you want to see? [0, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92]: 0\n
+\n
+Data of Table "db_migrations":\n
+\n
++----+----------------+--------------------+-------+---------------+------------+-------+\n
+| id | version | class | group | namespace | time | batch |\n
++----+----------------+--------------------+-------+---------------+------------+-------+\n
+| 14 | 20160428212500 | Tests\Support\D... | tests | Tests\Support | 1733827161 | 1 |\n
++----+----------------+--------------------+-------+---------------+------------+-------+\n
+\n
+' matches PCRE pattern "/Which table do you want to see\? \[0, 1, 2, 3, 4, 5, 6, 7, 8, 9.*?\]: a
+The "Which table do you want to see\?" field must be one of: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.*?./".
+
+E:\www\CodeIgniterProjects\dev\tests\system\Commands\Database\ShowTableInfoMockIOTest.php:63
+
+5) CodeIgniter\Commands\Database\ShowTableInfoTest::testDbTableShow
+Failed asserting that '+-----------+----------+----------+----------+----------+------+\n
+| hostname | database | username | DBDriver | DBPrefix | port |\n
++-----------+----------+----------+----------+----------+------+\n
+| 127.0.0.1 | :memory: | | SQLite3 | db_ | 3306 |\n
++-----------+----------+----------+----------+----------+------+\n
+\n
+The following is a list of the names of all database tables:\n
+\n
++-----+---------------------------+-------------+---------------+\n
+| ID | Table Name | Num of Rows | Num of Fields |\n
++-----+---------------------------+-------------+---------------+\n
+| 1 | db_migrations | 1 | 7 |\n
+| 93 | db_foo | 1 | 1 |\n
+| 94 | db_user | 0 | 7 |\n
+| 95 | db_job | 0 | 6 |\n
+| 96 | db_misc | 0 | 3 |\n
+| 97 | db_type_test | 0 | 21 |\n
+| 98 | db_empty | 0 | 4 |\n
+| 99 | db_secondary | 0 | 3 |\n
+| 100 | db_stringifypkey | 0 | 2 |\n
+| 101 | db_without_auto_increment | 0 | 2 |\n
+| 102 | db_ip_table | 0 | 2 |\n
++-----+---------------------------+-------------+---------------+\n
+\n
+\n
+' [ASCII](length: 1380) contains "+----+---------------------------+-------------+---------------+
+| ID | Table Name | Num of Rows | Num of Fields |
++----+---------------------------+-------------+---------------+" [ASCII](length: 194).
+
+E:\www\CodeIgniterProjects\dev\tests\system\Commands\Database\ShowTableInfoTest.php:103
+
+6) CodeIgniter\Security\CheckPhpIniTest::testCheckIni
+Failed asserting that two arrays are identical.
+--- Expected
++++ Actual
+@@ @@
+ Array &0 [
+- 'global' => '',
++ 'global' => '1',
+ 'current' => '1',
+ 'recommended' => '0',
+ 'remark' => '',
+ ]
+
+E:\www\CodeIgniterProjects\dev\tests\system\Security\CheckPhpIniTest.php:37
+
diff --git a/phpstan-baseline.php b/phpstan-baseline.php
index e8a65036bfc0..67df1ea199ca 100644
--- a/phpstan-baseline.php
+++ b/phpstan-baseline.php
@@ -12235,12 +12235,6 @@
'count' => 1,
'path' => __DIR__ . '/tests/system/CommonFunctionsTest.php',
];
-$ignoreErrors[] = [
- // identifier: missingType.iterableValue
- 'message' => '#^Method CodeIgniter\\\\CommonFunctionsTest\\:\\:provideCleanPathActuallyCleaningThePaths\\(\\) return type has no value type specified in iterable type iterable\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/tests/system/CommonFunctionsTest.php',
-];
$ignoreErrors[] = [
// identifier: codeigniter.modelArgumentType
'message' => '#^Parameter \\#1 \\$name of function model expects a valid class string, \'JobModel\' given\\.$#',
@@ -13071,15 +13065,15 @@
];
$ignoreErrors[] = [
// identifier: property.notFound
- 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$numberNative\\.$#',
+ 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$foundRows\\.$#',
'count' => 2,
- 'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
+ 'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/FoundRowsTest.php',
];
$ignoreErrors[] = [
// identifier: property.notFound
- 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$foundRows\\.$#',
+ 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$numberNative\\.$#',
'count' => 2,
- 'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/FoundRowsTest.php',
+ 'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
];
$ignoreErrors[] = [
// identifier: missingType.property
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7464323e4078..1a2197fd801f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,63 +1,64 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- tests/system
-
-
-
-
- system
-
-
- system/Commands/Generators/Views
- system/Debug/Toolbar/Views
- system/Pager/Views
- system/ThirdParty
- system/Validation/Views
- system/bootstrap.php
- system/ComposerScripts.php
- system/Config/Routes.php
- system/Test/bootstrap.php
- system/Test/ControllerTester.php
- system/Test/FeatureTestCase.php
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd"
+ bootstrap="system/Test/bootstrap.php"
+ backupGlobals="false"
+ beStrictAboutOutputDuringTests="true"
+ colors="true"
+ columns="max"
+ failOnRisky="true"
+ failOnWarning="true"
+ cacheDirectory="build/.phpunit.cache"
+>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tests/system
+
+
+
+
+ system
+
+
+ system/Commands/Generators/Views
+ system/Debug/Toolbar/Views
+ system/Pager/Views
+ system/ThirdParty
+ system/Validation/Views
+ system/bootstrap.php
+ system/ComposerScripts.php
+ system/Config/Routes.php
+ system/Test/bootstrap.php
+ system/Test/ControllerTester.php
+ system/Test/FeatureTestCase.php
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/index.php b/public/index.php
index 5ec58a7729c3..531ce7fb9247 100644
--- a/public/index.php
+++ b/public/index.php
@@ -27,10 +27,10 @@
*/
// Path to the front controller (this file)
-define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR);
+define('FCPATH', __DIR__ . '/');
// Ensure the current directory is pointing to the front controller's directory
-if (getcwd() . DIRECTORY_SEPARATOR !== FCPATH) {
+if (getcwd() . '/' !== FCPATH) {
chdir(FCPATH);
}
@@ -43,6 +43,20 @@
* and fires up an environment-specific bootstrapping.
*/
+/**
+ * A real path with identical slashes in Unix/Windows
+ */
+function _realpath(string $path): bool|string
+{
+ $realPath = realpath($path);
+
+ if (! $realPath) {
+ return false;
+ }
+
+ return str_replace('\\', '/', $realPath);
+}
+
// LOAD OUR PATHS CONFIG FILE
// This is the line that might need to be changed, depending on your folder structure.
require FCPATH . '../app/Config/Paths.php';
diff --git a/spark b/spark
index 992d044c9ee2..27ca86a1f376 100755
--- a/spark
+++ b/spark
@@ -57,7 +57,7 @@ ini_set('display_errors', '1');
*/
// Path to the front controller
-define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR);
+define('FCPATH', __DIR__ . '/public/');
// Ensure the current directory is pointing to the front controller's directory
chdir(FCPATH);
@@ -71,6 +71,20 @@ chdir(FCPATH);
* and fires up an environment-specific bootstrapping.
*/
+/**
+ * A real path with identical slashes in Unix/Windows
+ */
+function _realpath(string $path): bool|string
+{
+ $realPath = realpath($path);
+
+ if (! $realPath) {
+ return false;
+ }
+
+ return str_replace('\\', '/', $realPath);
+}
+
// LOAD OUR PATHS CONFIG FILE
// This is the line that might need to be changed, depending on your folder structure.
require FCPATH . '../app/Config/Paths.php';
diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php
index 0c5c7fab50fa..e960ebecdba6 100644
--- a/system/Autoloader/Autoloader.php
+++ b/system/Autoloader/Autoloader.php
@@ -139,7 +139,7 @@ private function loadComposerAutoloader(Modules $modules): void
// The path to the vendor directory.
// We do not want to enforce this, so set the constant if Composer was used.
if (! defined('VENDORPATH')) {
- define('VENDORPATH', dirname(COMPOSER_PATH) . DIRECTORY_SEPARATOR);
+ define('VENDORPATH', dirname(COMPOSER_PATH) . '/');
}
/** @var ClassLoader $composer */
@@ -199,16 +199,16 @@ public function addNamespace($namespace, ?string $path = null)
if (is_array($namespacedPath)) {
foreach ($namespacedPath as $dir) {
- $this->prefixes[$prefix][] = rtrim($dir, '\\/') . DIRECTORY_SEPARATOR;
+ $this->prefixes[$prefix][] = rtrim(normalize_path($dir), '\\/') . '/';
}
continue;
}
- $this->prefixes[$prefix][] = rtrim($namespacedPath, '\\/') . DIRECTORY_SEPARATOR;
+ $this->prefixes[$prefix][] = rtrim(normalize_path($namespacedPath), '\\/') . '/';
}
} else {
- $this->prefixes[trim($namespace, '\\')][] = rtrim($path, '\\/') . DIRECTORY_SEPARATOR;
+ $this->prefixes[trim($namespace, '\\')][] = rtrim(normalize_path($path), '\\/') . '/';
}
return $this;
@@ -286,7 +286,7 @@ protected function loadInNamespace(string $class)
foreach ($this->prefixes as $namespace => $directories) {
if (str_starts_with($class, $namespace)) {
- $relativeClassPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, strlen($namespace)));
+ $relativeClassPath = str_replace('\\', '/', substr($class, strlen($namespace)));
foreach ($directories as $directory) {
$directory = rtrim($directory, '\\/');
@@ -409,19 +409,21 @@ private function loadComposerNamespaces(ClassLoader $composer, array $composerPa
if ($only !== []) {
foreach ($packageList as $packageName => $data) {
if (in_array($packageName, $only, true) && isset($data['install_path'])) {
- $installPaths[] = $data['install_path'];
+ $installPaths[] = normalize_path($data['install_path']);
}
}
} else {
foreach ($packageList as $packageName => $data) {
if (! in_array($packageName, $exclude, true) && isset($data['install_path'])) {
- $installPaths[] = $data['install_path'];
+ $installPaths[] = normalize_path($data['install_path']);
}
}
}
$newPaths = [];
+ $namespacePaths = array_map(static fn (array $paths) => array_map(static fn (string $path) => normalize_path($path), $paths), $namespacePaths);
+
foreach ($namespacePaths as $namespace => $srcPaths) {
$add = false;
diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php
index 8e2564e00941..3f8842f492db 100644
--- a/system/Autoloader/FileLocator.php
+++ b/system/Autoloader/FileLocator.php
@@ -105,7 +105,7 @@ public function locateFile(string $file, ?string $folder = null, string $ext = '
// Check each path in the namespace
foreach ($paths as $path) {
// Ensure trailing slash
- $path = rtrim($path, '/') . '/';
+ $path = rtrim(normalize_path($path), '/') . '/';
// If we have a folder name, then the calling function
// expects this file to be within that folder, like 'Views',
@@ -196,7 +196,7 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp =
foreach ($this->getNamespaces() as $namespace) {
if (isset($namespace['path']) && is_file($namespace['path'] . $path)) {
$fullPath = $namespace['path'] . $path;
- $resolvedPath = realpath($fullPath);
+ $resolvedPath = _realpath($fullPath);
$fullPath = $resolvedPath !== false ? $resolvedPath : $fullPath;
if ($prioritizeApp) {
@@ -250,7 +250,7 @@ protected function getNamespaces()
if ($prefix === 'CodeIgniter') {
$system[] = [
'prefix' => $prefix,
- 'path' => rtrim($path, '\\/') . DIRECTORY_SEPARATOR,
+ 'path' => rtrim($path, '\\/') . '/',
];
continue;
@@ -258,7 +258,7 @@ protected function getNamespaces()
$namespaces[] = [
'prefix' => $prefix,
- 'path' => rtrim($path, '\\/') . DIRECTORY_SEPARATOR,
+ 'path' => rtrim($path, '\\/') . '/',
];
}
}
@@ -336,7 +336,7 @@ public function listFiles(string $path): array
foreach ($this->getNamespaces() as $namespace) {
$fullPath = $namespace['path'] . $path;
- $resolvedPath = realpath($fullPath);
+ $resolvedPath = _realpath($fullPath);
$fullPath = $resolvedPath !== false ? $resolvedPath : $fullPath;
if (! is_dir($fullPath)) {
@@ -399,7 +399,7 @@ public function listNamespaceFiles(string $prefix, string $path): array
protected function legacyLocate(string $file, ?string $folder = null)
{
$path = APPPATH . ($folder === null ? $file : $folder . '/' . $file);
- $resolvedPath = realpath($path);
+ $resolvedPath = _realpath($path);
$path = $resolvedPath !== false ? $resolvedPath : $path;
if (is_file($path)) {
diff --git a/system/Boot.php b/system/Boot.php
index 8b75908ded09..b60fd75742a5 100644
--- a/system/Boot.php
+++ b/system/Boot.php
@@ -181,27 +181,27 @@ protected static function definePathConstants(Paths $paths): void
{
// The path to the application directory.
if (! defined('APPPATH')) {
- define('APPPATH', realpath(rtrim($paths->appDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
+ define('APPPATH', _realpath(rtrim($paths->appDirectory, '\\/ ')) . '/');
}
// The path to the project root directory. Just above APPPATH.
if (! defined('ROOTPATH')) {
- define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR);
+ define('ROOTPATH', _realpath(APPPATH . '../') . '/');
}
// The path to the system directory.
if (! defined('SYSTEMPATH')) {
- define('SYSTEMPATH', realpath(rtrim($paths->systemDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
+ define('SYSTEMPATH', _realpath(rtrim($paths->systemDirectory, '\\/ ')) . '/');
}
// The path to the writable directory.
if (! defined('WRITEPATH')) {
- define('WRITEPATH', realpath(rtrim($paths->writableDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
+ define('WRITEPATH', _realpath(rtrim($paths->writableDirectory, '\\/ ')) . '/');
}
// The path to the tests directory
if (! defined('TESTPATH')) {
- define('TESTPATH', realpath(rtrim($paths->testsDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
+ define('TESTPATH', _realpath(rtrim($paths->testsDirectory, '\\/ ')) . '/');
}
}
diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php
index 2b468e622816..ca6c379a6fc8 100644
--- a/system/CLI/CLI.php
+++ b/system/CLI/CLI.php
@@ -324,7 +324,7 @@ public static function promptByMultipleKeys(string $text, array $options): array
$optsKey[] = $key;
}
$extraOutput = '[' . $extraOutputDefault . ', ' . implode(', ', $optsKey) . ']';
- $extraOutput = 'You can specify multiple values separated by commas.' . PHP_EOL . $extraOutput;
+ $extraOutput = 'You can specify multiple values separated by commas./n' . $extraOutput;
}
CLI::write($text);
@@ -462,11 +462,11 @@ public static function write(string $text = '', ?string $foreground = null, ?str
}
if (static::$lastWrite !== 'write') {
- $text = PHP_EOL . $text;
+ $text = "\n" . $text;
static::$lastWrite = 'write';
}
- static::fwrite(STDOUT, $text . PHP_EOL);
+ static::fwrite(STDOUT, $text . "\n");
}
/**
@@ -484,7 +484,7 @@ public static function error(string $text, string $foreground = 'light_red', ?st
$text = static::color($text, $foreground, $background);
}
- static::fwrite(STDERR, $text . PHP_EOL);
+ static::fwrite(STDERR, $text . "\n");
// return STDOUT color support
static::$isColored = $stdout;
@@ -818,7 +818,7 @@ public static function showProgress($thisStep = 1, int $totalSteps = 10)
// Write the progress bar
static::fwrite(STDOUT, "[\033[32m" . str_repeat('#', $step) . str_repeat('.', 10 - $step) . "\033[0m]");
// Textual representation...
- static::fwrite(STDOUT, sprintf(' %3d%% Complete', $percent) . PHP_EOL);
+ static::fwrite(STDOUT, sprintf(' %3d%% Complete', $percent) . "\n");
} else {
static::fwrite(STDOUT, "\007");
}
@@ -849,10 +849,10 @@ public static function wrap(?string $string = null, int $max = 0, int $padLeft =
$max -= $padLeft;
- $lines = wordwrap($string, $max, PHP_EOL);
+ $lines = wordwrap($string, $max, "\n");
if ($padLeft > 0) {
- $lines = explode(PHP_EOL, $lines);
+ $lines = explode("\n", $lines);
$first = true;
@@ -864,7 +864,7 @@ public static function wrap(?string $string = null, int $max = 0, int $padLeft =
}
});
- $lines = implode(PHP_EOL, $lines);
+ $lines = implode("\n", $lines);
}
return $lines;
@@ -1094,15 +1094,15 @@ public static function table(array $tbody, array $thead = [])
foreach ($tableRows[$row] as $col) {
$cols .= str_repeat('-', static::strlen((string) $col) + 2) . '+';
}
- $table .= $cols . PHP_EOL;
+ $table .= $cols . "\n";
}
// Set the columns borders
- $table .= '| ' . implode(' | ', $tableRows[$row]) . ' |' . PHP_EOL;
+ $table .= '| ' . implode(' | ', $tableRows[$row]) . " |\n";
// Set the thead and table borders-bottom
if (($row === 0 && $thead !== []) || ($row + 1 === $totalRows)) {
- $table .= $cols . PHP_EOL;
+ $table .= $cols . "\n";
}
}
diff --git a/system/CLI/GeneratorTrait.php b/system/CLI/GeneratorTrait.php
index 6a061a36b8b3..02ca71e19b8a 100644
--- a/system/CLI/GeneratorTrait.php
+++ b/system/CLI/GeneratorTrait.php
@@ -439,24 +439,24 @@ protected function buildPath(string $class): string
return '';
}
- $realpath = realpath($base);
+ $realpath = _realpath($base);
$base = ($realpath !== false) ? $realpath : $base;
- $file = $base . DIRECTORY_SEPARATOR
+ $file = $base . '/'
. str_replace(
'\\',
- DIRECTORY_SEPARATOR,
+ '/',
trim(str_replace($namespace . '\\', '', $class), '\\')
) . '.php';
return implode(
- DIRECTORY_SEPARATOR,
+ '/',
array_slice(
- explode(DIRECTORY_SEPARATOR, $file),
+ explode('/', $file),
0,
-1
)
- ) . DIRECTORY_SEPARATOR . $this->basename($file);
+ ) . '/' . $this->basename($file);
}
/**
diff --git a/system/CLI/InputOutput.php b/system/CLI/InputOutput.php
index b69c19e2eee1..7bb34be92653 100644
--- a/system/CLI/InputOutput.php
+++ b/system/CLI/InputOutput.php
@@ -69,6 +69,8 @@ public function input(?string $prefix = null): string
*/
public function fwrite($handle, string $string): void
{
+ $string = str_replace("\r\n", "\n", $string);
+
if (! is_cli()) {
echo $string;
diff --git a/system/Cache/Handlers/FileHandler.php b/system/Cache/Handlers/FileHandler.php
index a86a45e83d00..2237101e5e70 100644
--- a/system/Cache/Handlers/FileHandler.php
+++ b/system/Cache/Handlers/FileHandler.php
@@ -306,10 +306,10 @@ protected function deleteFiles(string $path, bool $delDir = false, bool $htdocs
while (false !== ($filename = @readdir($currentDir))) {
if ($filename !== '.' && $filename !== '..') {
- if (is_dir($path . DIRECTORY_SEPARATOR . $filename) && $filename[0] !== '.') {
- $this->deleteFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $htdocs, $_level + 1);
+ if (is_dir($path . '/' . $filename) && $filename[0] !== '.') {
+ $this->deleteFiles($path . '/' . $filename, $delDir, $htdocs, $_level + 1);
} elseif (! $htdocs || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) {
- @unlink($path . DIRECTORY_SEPARATOR . $filename);
+ @unlink($path . '/' . $filename);
}
}
}
@@ -340,13 +340,13 @@ protected function getDirFileInfo(string $sourceDir, bool $topLevelOnly = true,
// reset the array and make sure $source_dir has a trailing slash on the initial call
if ($_recursion === false) {
$_filedata = [];
- $sourceDir = rtrim(realpath($sourceDir) ?: $sourceDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $sourceDir = rtrim(_realpath($sourceDir) ?: $sourceDir, '/') . '/';
}
// Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
while (false !== ($file = readdir($fp))) {
if (is_dir($sourceDir . $file) && $file[0] !== '.' && $topLevelOnly === false) {
- $this->getDirFileInfo($sourceDir . $file . DIRECTORY_SEPARATOR, $topLevelOnly, true);
+ $this->getDirFileInfo($sourceDir . $file . '/', $topLevelOnly, true);
} elseif (! is_dir($sourceDir . $file) && $file[0] !== '.') {
$_filedata[$file] = $this->getFileInfo($sourceDir . $file);
$_filedata[$file]['relative_path'] = $relativePath;
diff --git a/system/Commands/Database/CreateDatabase.php b/system/Commands/Database/CreateDatabase.php
index 0c8d2016dc93..a3e3fdfe81da 100644
--- a/system/Commands/Database/CreateDatabase.php
+++ b/system/Commands/Database/CreateDatabase.php
@@ -109,7 +109,7 @@ public function run(array $params)
$config->{$group}['database'] = $name;
if ($name !== ':memory:') {
- $dbName = ! str_contains($name, DIRECTORY_SEPARATOR) ? WRITEPATH . $name : $name;
+ $dbName = ! str_contains($name, '/') ? WRITEPATH . $name : $name;
if (is_file($dbName)) {
CLI::error("Database \"{$dbName}\" already exists.", 'light_gray', 'red');
diff --git a/system/Commands/Generators/TestGenerator.php b/system/Commands/Generators/TestGenerator.php
index 35019c72b826..a9568236130a 100644
--- a/system/Commands/Generators/TestGenerator.php
+++ b/system/Commands/Generators/TestGenerator.php
@@ -150,24 +150,24 @@ protected function buildPath(string $class): string
return '';
}
- $realpath = realpath($base);
+ $realpath = _realpath($base);
$base = ($realpath !== false) ? $realpath : $base;
- $file = $base . DIRECTORY_SEPARATOR
+ $file = $base . '/'
. str_replace(
'\\',
- DIRECTORY_SEPARATOR,
+ '/',
trim(str_replace($namespace . '\\', '', $class), '\\')
) . '.php';
return implode(
- DIRECTORY_SEPARATOR,
+ '/',
array_slice(
- explode(DIRECTORY_SEPARATOR, $file),
+ explode('/', $file),
0,
-1
)
- ) . DIRECTORY_SEPARATOR . $this->basename($file);
+ ) . '/' . $this->basename($file);
}
/**
diff --git a/system/Commands/Translation/LocalizationFinder.php b/system/Commands/Translation/LocalizationFinder.php
index e7d4eff69663..41705940051d 100644
--- a/system/Commands/Translation/LocalizationFinder.php
+++ b/system/Commands/Translation/LocalizationFinder.php
@@ -17,6 +17,7 @@
use CodeIgniter\CLI\CLI;
use CodeIgniter\Helpers\Array\ArrayHelper;
use Config\App;
+use FilesystemIterator;
use Locale;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
@@ -62,7 +63,7 @@ public function run(array $params)
$this->languagePath = $currentDir . 'Language';
if (ENVIRONMENT === 'testing') {
- $currentDir = SUPPORTPATH . 'Services' . DIRECTORY_SEPARATOR;
+ $currentDir = SUPPORTPATH . 'Services/';
$this->languagePath = SUPPORTPATH . 'Language';
}
@@ -80,7 +81,7 @@ public function run(array $params)
}
if (is_string($optionDir)) {
- $tempCurrentDir = realpath($currentDir . $optionDir);
+ $tempCurrentDir = _realpath($currentDir . $optionDir);
if ($tempCurrentDir === false) {
CLI::error('Error: Directory must be located in "' . $currentDir . '"');
@@ -109,7 +110,7 @@ private function process(string $currentDir, string $currentLocale): void
$tableRows = [];
$countNewKeys = 0;
- $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($currentDir));
+ $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($currentDir, FilesystemIterator::UNIX_PATHS));
$files = iterator_to_array($iterator, true);
ksort($files);
@@ -126,7 +127,7 @@ private function process(string $currentDir, string $currentLocale): void
foreach ($languageFoundGroups as $langFileName) {
$languageStoredKeys = [];
- $languageFilePath = $this->languagePath . DIRECTORY_SEPARATOR . $currentLocale . DIRECTORY_SEPARATOR . $langFileName . '.php';
+ $languageFilePath = $this->languagePath . '/' . $currentLocale . '/' . $langFileName . '.php';
if (is_file($languageFilePath)) {
// Load old localization
@@ -199,11 +200,12 @@ private function findTranslationsInFile($file): array
}
foreach ($matches[1] as $phraseKey) {
- $phraseKeys = explode('.', $phraseKey);
+ $phraseKeys = explode('.', $phraseKey);
+ $realPathFile = normalize_path($file->getRealPath());
// Language key not have Filename or Lang key
if (count($phraseKeys) < 2) {
- $badLanguageKeys[] = [mb_substr($file->getRealPath(), mb_strlen(ROOTPATH)), $phraseKey];
+ $badLanguageKeys[] = [mb_substr($realPathFile, mb_strlen(ROOTPATH)), $phraseKey];
continue;
}
@@ -214,7 +216,7 @@ private function findTranslationsInFile($file): array
|| ($languageFileName === '' && $phraseKeys[0] === '');
if ($isEmptyNestedArray) {
- $badLanguageKeys[] = [mb_substr($file->getRealPath(), mb_strlen(ROOTPATH)), $phraseKey];
+ $badLanguageKeys[] = [mb_substr($realPathFile, mb_strlen(ROOTPATH)), $phraseKey];
continue;
}
@@ -233,7 +235,7 @@ private function findTranslationsInFile($file): array
private function isIgnoredFile(SplFileInfo $file): bool
{
- if ($file->isDir() || $this->isSubDirectory($file->getRealPath(), $this->languagePath)) {
+ if ($file->isDir() || $this->isSubDirectory(normalize_path($file->getRealPath()), $this->languagePath)) {
return true;
}
@@ -375,7 +377,7 @@ private function findLanguageKeysInFiles(array $files): array
continue;
}
- $this->writeIsVerbose('File found: ' . mb_substr($file->getRealPath(), mb_strlen(APPPATH)));
+ $this->writeIsVerbose('File found: ' . mb_substr(normalize_path($file->getRealPath()), mb_strlen(APPPATH)));
$countFiles++;
$findInFile = $this->findTranslationsInFile($file);
diff --git a/system/Commands/Utilities/ConfigCheck.php b/system/Commands/Utilities/ConfigCheck.php
index 7d6dc332ca45..7d5748649b26 100644
--- a/system/Commands/Utilities/ConfigCheck.php
+++ b/system/Commands/Utilities/ConfigCheck.php
@@ -131,7 +131,7 @@ private function getKintD(object $config): string
$output = trim($output);
- $lines = explode("\n", $output);
+ $lines = explode(PHP_EOL, $output);
array_splice($lines, 0, 3);
array_splice($lines, -3);
diff --git a/system/Common.php b/system/Common.php
index 20afcd3cfbf4..d8dd711df670 100644
--- a/system/Common.php
+++ b/system/Common.php
@@ -96,17 +96,17 @@ function clean_path(string $path): string
{
// Resolve relative paths
try {
- $path = realpath($path) ?: $path;
+ $path = _realpath($path) ?: $path;
} catch (ErrorException|ValueError) {
$path = 'error file path: ' . urlencode($path);
}
return match (true) {
- str_starts_with($path, APPPATH) => 'APPPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(APPPATH)),
- str_starts_with($path, SYSTEMPATH) => 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(SYSTEMPATH)),
- str_starts_with($path, FCPATH) => 'FCPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(FCPATH)),
- defined('VENDORPATH') && str_starts_with($path, VENDORPATH) => 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(VENDORPATH)),
- str_starts_with($path, ROOTPATH) => 'ROOTPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(ROOTPATH)),
+ str_starts_with($path, APPPATH) => 'APPPATH/' . substr($path, strlen(APPPATH)),
+ str_starts_with($path, SYSTEMPATH) => 'SYSTEMPATH/' . substr($path, strlen(SYSTEMPATH)),
+ str_starts_with($path, FCPATH) => 'FCPATH/' . substr($path, strlen(FCPATH)),
+ defined('VENDORPATH') && str_starts_with($path, VENDORPATH) => 'VENDORPATH/' . substr($path, strlen(VENDORPATH)),
+ str_starts_with($path, ROOTPATH) => 'ROOTPATH/' . substr($path, strlen(ROOTPATH)),
default => $path,
};
}
@@ -611,9 +611,9 @@ function helper($filenames): void
$paths = $loader->search('Helpers/' . $filename);
foreach ($paths as $path) {
- if (str_starts_with($path, APPPATH . 'Helpers' . DIRECTORY_SEPARATOR)) {
+ if (str_starts_with($path, APPPATH . 'Helpers/')) {
$appHelper = $path;
- } elseif (str_starts_with($path, SYSTEMPATH . 'Helpers' . DIRECTORY_SEPARATOR)) {
+ } elseif (str_starts_with($path, SYSTEMPATH . 'Helpers/')) {
$systemHelper = $path;
} else {
$localIncludes[] = $path;
@@ -1261,3 +1261,13 @@ function trait_uses_recursive($trait)
return $traits;
}
}
+
+if (! function_exists('normalize_path')) {
+ /**
+ * Converts backslash to paths for compatibility in Unix/Windows
+ */
+ function normalize_path(string $path): string
+ {
+ return str_replace('\\', '/', $path);
+ }
+}
diff --git a/system/ComposerScripts.php b/system/ComposerScripts.php
index 661247dab532..407b335c3184 100644
--- a/system/ComposerScripts.php
+++ b/system/ComposerScripts.php
@@ -94,7 +94,7 @@ public static function postUpdate()
private static function recursiveDelete(string $directory): void
{
if (! is_dir($directory)) {
- echo sprintf('Cannot recursively delete "%s" as it does not exist.', $directory) . PHP_EOL;
+ echo sprintf('Cannot recursively delete "%s" as it does not exist.', $directory) . "\n";
return;
}
@@ -136,7 +136,7 @@ private static function recursiveMirror(string $originDir, string $targetDir): v
}
if (! @mkdir($targetDir, 0755, true)) {
- echo sprintf('Cannot create the target directory: "%s"', $targetDir) . PHP_EOL;
+ echo sprintf('Cannot create the target directory: "%s"', $targetDir) . "\n";
exit(1);
}
diff --git a/system/Config/DotEnv.php b/system/Config/DotEnv.php
index eb3e6c5e3c9d..baec5bf02352 100644
--- a/system/Config/DotEnv.php
+++ b/system/Config/DotEnv.php
@@ -34,7 +34,7 @@ class DotEnv
*/
public function __construct(string $path, string $file = '.env')
{
- $this->path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file;
+ $this->path = rtrim($path, '\\/') . '/' . $file;
}
/**
diff --git a/system/Config/Factories.php b/system/Config/Factories.php
index 6091ab42c5eb..4354e3e861e1 100644
--- a/system/Config/Factories.php
+++ b/system/Config/Factories.php
@@ -310,7 +310,7 @@ class_exists($alias, false)
}
// No namespace? Search for it
// Check all namespaces, prioritizing App and modules
- elseif (($files = $locator->search($options['path'] . DIRECTORY_SEPARATOR . $alias)) === []) {
+ elseif (($files = $locator->search($options['path'] . '/' . $alias)) === []) {
return null;
}
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index 5cac985631f1..c3c99c7d159d 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -466,8 +466,8 @@ public function initialize()
if (! $this->connID) {
throw new DatabaseException(sprintf(
'Unable to connect to the database.%s%s',
- PHP_EOL,
- implode(PHP_EOL, $connectionErrors)
+ "\n",
+ implode("\n", $connectionErrors)
));
}
}
diff --git a/system/Database/MigrationRunner.php b/system/Database/MigrationRunner.php
index 46d8be709d3e..1a7cdedce817 100644
--- a/system/Database/MigrationRunner.php
+++ b/system/Database/MigrationRunner.php
@@ -417,8 +417,8 @@ public function findNamespaceMigrations(string $namespace): array
$locator = service('locator', true);
if (! empty($this->path)) {
- helper('filesystem');
- $dir = rtrim($this->path, DIRECTORY_SEPARATOR) . '/';
+ helper(['filesystem']);
+ $dir = rtrim($this->path, '/') . '/';
$files = get_filenames($dir, true, false, false);
} else {
$files = $locator->listNamespaceFiles($namespace, '/Database/Migrations/');
diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php
index f19938a439f0..33df9cd49284 100644
--- a/system/Database/SQLite3/Connection.php
+++ b/system/Database/SQLite3/Connection.php
@@ -103,7 +103,7 @@ public function connect(bool $persistent = false)
}
try {
- if ($this->database !== ':memory:' && ! str_contains($this->database, DIRECTORY_SEPARATOR)) {
+ if ($this->database !== ':memory:' && ! str_contains($this->database, '/')) {
$this->database = WRITEPATH . $this->database;
}
diff --git a/system/Debug/BaseExceptionHandler.php b/system/Debug/BaseExceptionHandler.php
index 4305265d2d2c..fba317f3eb4d 100644
--- a/system/Debug/BaseExceptionHandler.php
+++ b/system/Debug/BaseExceptionHandler.php
@@ -47,7 +47,7 @@ public function __construct(ExceptionsConfig $config)
$this->obLevel = ob_get_level();
if ($this->viewPath === null) {
- $this->viewPath = rtrim($this->config->errorViewPath, '\\/ ') . DIRECTORY_SEPARATOR;
+ $this->viewPath = rtrim($this->config->errorViewPath, '\\/ ') . '/';
}
}
diff --git a/system/Debug/ExceptionHandler.php b/system/Debug/ExceptionHandler.php
index d63b599bf6c1..3dd4accf3656 100644
--- a/system/Debug/ExceptionHandler.php
+++ b/system/Debug/ExceptionHandler.php
@@ -95,10 +95,10 @@ public function handle(
}
// Determine possible directories of error views
- $addPath = ($request instanceof IncomingRequest ? 'html' : 'cli') . DIRECTORY_SEPARATOR;
+ $addPath = ($request instanceof IncomingRequest ? 'html' : 'cli') . '/';
$path = $this->viewPath . $addPath;
$altPath = rtrim((new Paths())->viewDirectory, '\\/ ')
- . DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . $addPath;
+ . '/errors/' . $addPath;
// Determine the views
$view = $this->determineView($exception, $path, $statusCode);
@@ -146,7 +146,7 @@ protected function determineView(
return 'error_404.php';
}
- $templatePath = rtrim($templatePath, '\\/ ') . DIRECTORY_SEPARATOR;
+ $templatePath = rtrim($templatePath, '\\/ ') . '/';
// Allow for custom views based upon the status code
if (is_file($templatePath . 'error_' . $statusCode . '.php')) {
diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php
index b939e208fd21..073997960adf 100644
--- a/system/Debug/Toolbar.php
+++ b/system/Debug/Toolbar.php
@@ -424,14 +424,14 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r
$kintScript = substr($kintScript, 0, strpos($kintScript, '') + 8);
$kintScript = ($kintScript === '0') ? '' : $kintScript;
- $script = PHP_EOL
+ $script = "\n"
. ''
. ''
. ''
. $kintScript
- . PHP_EOL;
+ . "\n";
if (str_contains((string) $response->getBody(), '')) {
$response->setBody(
diff --git a/system/Files/File.php b/system/Files/File.php
index 1b9aefbb6694..7d9c38df3ba2 100644
--- a/system/Files/File.php
+++ b/system/Files/File.php
@@ -200,12 +200,12 @@ public function getDestination(string $destination, string $delimiter = '_', int
$i = end($parts);
array_pop($parts);
$parts[] = ++$i;
- $destination = $info['dirname'] . DIRECTORY_SEPARATOR . implode($delimiter, $parts) . $extension;
+ $destination = $info['dirname'] . '/' . implode($delimiter, $parts) . $extension;
} else {
- $destination = $info['dirname'] . DIRECTORY_SEPARATOR . $info['filename'] . $delimiter . ++$i . $extension;
+ $destination = $info['dirname'] . '/' . $info['filename'] . $delimiter . ++$i . $extension;
}
} else {
- $destination = $info['dirname'] . DIRECTORY_SEPARATOR . $info['filename'] . $delimiter . ++$i . $extension;
+ $destination = $info['dirname'] . '/' . $info['filename'] . $delimiter . ++$i . $extension;
}
}
@@ -224,4 +224,9 @@ private function getSizeByUnitInternal(int $fileSizeBase, FileSizeUnit $unit, in
return $size;
}
+
+ public function getRealPath(): false|string
+ {
+ return parent::getRealPath() !== false ? normalize_path(parent::getRealPath()) : false;
+ }
}
diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php
index 1ffabc34b056..ef2e5a7b5297 100644
--- a/system/Helpers/filesystem_helper.php
+++ b/system/Helpers/filesystem_helper.php
@@ -31,11 +31,12 @@
function directory_map(string $sourceDir, int $directoryDepth = 0, bool $hidden = false): array
{
try {
- $fp = opendir($sourceDir);
+ $sourceDir = normalize_path($sourceDir);
+ $fp = opendir($sourceDir);
$fileData = [];
$newDepth = $directoryDepth - 1;
- $sourceDir = rtrim($sourceDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $sourceDir = rtrim($sourceDir, '/') . '/';
while (false !== ($file = readdir($fp))) {
// Remove '.', '..', and hidden files [optional]
@@ -44,7 +45,7 @@ function directory_map(string $sourceDir, int $directoryDepth = 0, bool $hidden
}
if (is_dir($sourceDir . $file)) {
- $file .= DIRECTORY_SEPARATOR;
+ $file .= '/';
}
if (($directoryDepth < 1 || $newDepth > 0) && is_dir($sourceDir . $file)) {
@@ -88,7 +89,7 @@ function directory_mirror(string $originDir, string $targetDir, bool $overwrite
* @var SplFileInfo $file
*/
foreach (new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($originDir, FilesystemIterator::SKIP_DOTS),
+ new RecursiveDirectoryIterator($originDir, FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS),
RecursiveIteratorIterator::SELF_FIRST
) as $file) {
$origin = $file->getPathname();
@@ -155,12 +156,12 @@ function write_file(string $path, string $data, string $mode = 'wb'): bool
*/
function delete_files(string $path, bool $delDir = false, bool $htdocs = false, bool $hidden = false): bool
{
- $path = realpath($path) ?: $path;
- $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $path = _realpath($path) ?: $path;
+ $path = rtrim($path, '/') . '/';
try {
foreach (new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
+ new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS | RecursiveDirectoryIterator::UNIX_PATHS),
RecursiveIteratorIterator::CHILD_FIRST
) as $object) {
$filename = $object->getFilename();
@@ -208,12 +209,12 @@ function get_filenames(
): array {
$files = [];
- $sourceDir = realpath($sourceDir) ?: $sourceDir;
- $sourceDir = rtrim($sourceDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $sourceDir = _realpath($sourceDir) ?: $sourceDir;
+ $sourceDir = rtrim($sourceDir, '/') . '/';
try {
foreach (new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
+ new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::UNIX_PATHS),
RecursiveIteratorIterator::SELF_FIRST
) as $name => $object) {
$basename = pathinfo($name, PATHINFO_BASENAME);
@@ -265,13 +266,13 @@ function get_dir_file_info(string $sourceDir, bool $topLevelOnly = true, bool $r
// reset the array and make sure $source_dir has a trailing slash on the initial call
if ($recursion === false) {
$fileData = [];
- $sourceDir = rtrim(realpath($sourceDir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $sourceDir = rtrim(_realpath($sourceDir), '/') . '/';
}
// Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
while (false !== ($file = readdir($fp))) {
if (is_dir($sourceDir . $file) && $file[0] !== '.' && $topLevelOnly === false) {
- get_dir_file_info($sourceDir . $file . DIRECTORY_SEPARATOR, $topLevelOnly, true);
+ get_dir_file_info($sourceDir . $file . '/', $topLevelOnly, true);
} elseif ($file[0] !== '.') {
$fileData[$file] = get_file_info($sourceDir . $file);
$fileData[$file]['relative_path'] = $relativePath;
@@ -303,7 +304,9 @@ function get_dir_file_info(string $sourceDir, bool $topLevelOnly = true, bool $r
*/
function get_file_info(string $file, $returnedValues = ['name', 'server_path', 'size', 'date'])
{
- if (! is_file($file)) {
+ $file = _realpath($file);
+
+ if ($file === false || ! is_file($file)) {
return null;
}
@@ -442,13 +445,14 @@ function set_realpath(string $path, bool $checkExistence = false): string
}
// Resolve the path
- if (realpath($path) !== false) {
- $path = realpath($path);
+ $resolvedPath = _realpath($path);
+ if ($resolvedPath !== false) {
+ $path = $resolvedPath;
} elseif ($checkExistence && ! is_dir($path) && ! is_file($path)) {
throw new InvalidArgumentException('Not a valid path: ' . $path);
}
// Add a trailing slash, if this is a directory
- return is_dir($path) ? rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $path;
+ return is_dir($path) ? rtrim($path, '/') . '/' : $path;
}
}
diff --git a/system/Pager/Views/default_head.php b/system/Pager/Views/default_head.php
index c233e5eace22..6f41d03162a7 100644
--- a/system/Pager/Views/default_head.php
+++ b/system/Pager/Views/default_head.php
@@ -17,11 +17,11 @@
$pager->setSurroundCount(0);
if ($pager->hasPrevious()) {
- echo '' . PHP_EOL;
+ echo '' . "\n";
}
-echo '' . PHP_EOL;
+echo '' . "\n";
if ($pager->hasNext()) {
- echo '' . PHP_EOL;
+ echo '' . "\n";
}
diff --git a/system/Publisher/Publisher.php b/system/Publisher/Publisher.php
index d65765947db1..8c86ee3f396e 100644
--- a/system/Publisher/Publisher.php
+++ b/system/Publisher/Publisher.php
@@ -238,9 +238,9 @@ final public function getDestination(): string
final public function getScratch(): string
{
if ($this->scratch === null) {
- $this->scratch = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . bin2hex(random_bytes(6)) . DIRECTORY_SEPARATOR;
+ $this->scratch = rtrim(sys_get_temp_dir(), '/') . '/' . bin2hex(random_bytes(6)) . '/';
mkdir($this->scratch, 0700);
- $this->scratch = realpath($this->scratch) ? realpath($this->scratch) . DIRECTORY_SEPARATOR
+ $this->scratch = _realpath($this->scratch) ? _realpath($this->scratch) . '/'
: $this->scratch;
}
diff --git a/system/Test/Mock/MockInputOutput.php b/system/Test/Mock/MockInputOutput.php
index fb76781a177e..bc631ff8fc17 100644
--- a/system/Test/Mock/MockInputOutput.php
+++ b/system/Test/Mock/MockInputOutput.php
@@ -115,7 +115,7 @@ public function input(?string $prefix = null): string
PhpStreamWrapper::setContent($input);
$userInput = parent::input($prefix);
- $this->outputs[] = CITestStreamFilter::$buffer . $input . PHP_EOL;
+ $this->outputs[] = CITestStreamFilter::$buffer . $input . "\n";
PhpStreamWrapper::restore();
diff --git a/system/Test/bootstrap.php b/system/Test/bootstrap.php
index d2b47aaf21fb..2c039dadbeb7 100644
--- a/system/Test/bootstrap.php
+++ b/system/Test/bootstrap.php
@@ -40,13 +40,27 @@
* so they are available in the config files that are loaded.
*/
+/**
+ * A real path with identical slashes in Unix/Windows
+ */
+function _realpath(string $path): bool|string
+{
+ $realPath = realpath($path);
+
+ if (! $realPath) {
+ return false;
+ }
+
+ return str_replace('\\', '/', $realPath);
+}
+
// Often these constants are pre-defined, but query the current directory structure as a fallback
-defined('HOMEPATH') || define('HOMEPATH', realpath(rtrim(getcwd(), '\\/ ')) . DIRECTORY_SEPARATOR);
+defined('HOMEPATH') || define('HOMEPATH', _realpath(rtrim(getcwd(), '\\/ ')) . '/');
$source = is_dir(HOMEPATH . 'app')
? HOMEPATH
: (is_dir('vendor/codeigniter4/framework/') ? 'vendor/codeigniter4/framework/' : 'vendor/codeigniter4/codeigniter4/');
-defined('CONFIGPATH') || define('CONFIGPATH', realpath($source . 'app/Config') . DIRECTORY_SEPARATOR);
-defined('PUBLICPATH') || define('PUBLICPATH', realpath($source . 'public') . DIRECTORY_SEPARATOR);
+defined('CONFIGPATH') || define('CONFIGPATH', _realpath($source . 'app/Config') . '/');
+defined('PUBLICPATH') || define('PUBLICPATH', _realpath($source . 'public') . '/');
unset($source);
// LOAD OUR PATHS CONFIG FILE
@@ -55,18 +69,18 @@
$paths = new Paths();
// Define necessary framework path constants
-defined('APPPATH') || define('APPPATH', realpath(rtrim($paths->appDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
-defined('ROOTPATH') || define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR);
-defined('SYSTEMPATH') || define('SYSTEMPATH', realpath(rtrim($paths->systemDirectory, '\\/')) . DIRECTORY_SEPARATOR);
-defined('WRITEPATH') || define('WRITEPATH', realpath(rtrim($paths->writableDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
-defined('TESTPATH') || define('TESTPATH', realpath(HOMEPATH . 'tests/') . DIRECTORY_SEPARATOR);
-
-defined('CIPATH') || define('CIPATH', realpath(SYSTEMPATH . '../') . DIRECTORY_SEPARATOR);
-defined('FCPATH') || define('FCPATH', realpath(PUBLICPATH) . DIRECTORY_SEPARATOR);
-
-defined('SUPPORTPATH') || define('SUPPORTPATH', realpath(TESTPATH . '_support/') . DIRECTORY_SEPARATOR);
-defined('COMPOSER_PATH') || define('COMPOSER_PATH', (string) realpath(HOMEPATH . 'vendor/autoload.php'));
-defined('VENDORPATH') || define('VENDORPATH', realpath(HOMEPATH . 'vendor') . DIRECTORY_SEPARATOR);
+defined('APPPATH') || define('APPPATH', _realpath(rtrim($paths->appDirectory, '\\/ ')) . '/');
+defined('ROOTPATH') || define('ROOTPATH', _realpath(APPPATH . '../') . '/');
+defined('SYSTEMPATH') || define('SYSTEMPATH', _realpath(rtrim($paths->systemDirectory, '\\/')) . '/');
+defined('WRITEPATH') || define('WRITEPATH', _realpath(rtrim($paths->writableDirectory, '\\/ ')) . '/');
+defined('TESTPATH') || define('TESTPATH', _realpath(HOMEPATH . 'tests/') . '/');
+
+defined('CIPATH') || define('CIPATH', _realpath(SYSTEMPATH . '../') . '/');
+defined('FCPATH') || define('FCPATH', _realpath(PUBLICPATH) . '/');
+
+defined('SUPPORTPATH') || define('SUPPORTPATH', _realpath(TESTPATH . '_support/') . '/');
+defined('COMPOSER_PATH') || define('COMPOSER_PATH', (string) _realpath(HOMEPATH . 'vendor/autoload.php'));
+defined('VENDORPATH') || define('VENDORPATH', _realpath(HOMEPATH . 'vendor') . '/');
/*
*---------------------------------------------------------------
diff --git a/system/View/View.php b/system/View/View.php
index b54472ed0921..ae64cf004f3c 100644
--- a/system/View/View.php
+++ b/system/View/View.php
@@ -281,9 +281,9 @@ public function render(string $view, ?array $options = null, ?bool $saveData = n
$this->renderVars['file'] = clean_path($this->renderVars['file']);
$this->renderVars['file'] = ++$this->viewsCount . ' ' . $this->renderVars['file'];
- $output = '' . PHP_EOL
- . $output . PHP_EOL
- . '' . PHP_EOL;
+ $output = '\n"
+ . $output . "\n"
+ . '\n";
}
}
diff --git a/system/rewrite.php b/system/rewrite.php
index aba4560446fc..a8d99f5d61ba 100644
--- a/system/rewrite.php
+++ b/system/rewrite.php
@@ -29,7 +29,7 @@
$_SERVER['SCRIPT_NAME'] = '/index.php';
// Full path
-$path = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . ltrim($uri, '/');
+$path = $_SERVER['DOCUMENT_ROOT'] . '/' . ltrim($uri, '/');
// If $path is an existing file or folder within the public folder
// then let the request handle it like normal.
@@ -41,5 +41,5 @@
// Otherwise, we'll load the index file and let
// the framework handle the request from here.
-require_once $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'index.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/index.php';
// @codeCoverageIgnoreEnd
diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php
index 328a7834e4fc..5f3d68978d39 100644
--- a/tests/system/Autoloader/AutoloaderTest.php
+++ b/tests/system/Autoloader/AutoloaderTest.php
@@ -114,13 +114,11 @@ public function testServiceAutoLoaderFromShareInstances(): void
$classLoader = $this->getPrivateMethodInvoker(service('autoloader'), 'loadInNamespace');
// look for Home controller, as that should be in base repo
- $actual = $classLoader(Home::class);
- $expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
-
- $resolvedPath = realpath($actual);
+ $actual = $classLoader(Home::class);
+ $resolvedPath = _realpath($actual);
$actual = $resolvedPath !== false ? $resolvedPath : $actual;
- $this->assertSame($expected, $actual);
+ $this->assertSame(APPPATH . 'Controllers/Home.php', $actual);
}
public function testServiceAutoLoader(): void
@@ -132,33 +130,28 @@ public function testServiceAutoLoader(): void
$classLoader = $this->getPrivateMethodInvoker($autoloader, 'loadInNamespace');
// look for Home controller, as that should be in base repo
- $actual = $classLoader(Home::class);
- $expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
-
- $resolvedPath = realpath($actual);
+ $actual = $classLoader(Home::class);
+ $resolvedPath = _realpath($actual);
$actual = $resolvedPath !== false ? $resolvedPath : $actual;
- $this->assertSame($expected, $actual);
+ $this->assertSame(APPPATH . 'Controllers/Home.php', $actual);
$autoloader->unregister();
}
public function testExistingFile(): void
{
- $actual = ($this->classLoader)(Home::class);
- $expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
- $this->assertSame($expected, $actual);
+ $actual = ($this->classLoader)(Home::class);
+ $this->assertSame(APPPATH . 'Controllers/Home.php', $actual);
- $actual = ($this->classLoader)('CodeIgniter\Helpers\array_helper');
- $expected = SYSTEMPATH . 'Helpers' . DIRECTORY_SEPARATOR . 'array_helper.php';
- $this->assertSame($expected, $actual);
+ $actual = ($this->classLoader)('CodeIgniter\Helpers\array_helper');
+ $this->assertSame(SYSTEMPATH . 'Helpers/array_helper.php', $actual);
}
public function testMatchesWithPrecedingSlash(): void
{
- $actual = ($this->classLoader)(Home::class);
- $expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
- $this->assertSame($expected, $actual);
+ $actual = ($this->classLoader)(Home::class);
+ $this->assertSame(APPPATH . 'Controllers/Home.php', $actual);
}
public function testMissingFile(): void
@@ -172,10 +165,9 @@ public function testAddNamespaceWorks(): void
$this->loader->addNamespace('My\App', __DIR__);
- $actual = ($this->classLoader)('My\App\AutoloaderTest');
- $expected = __FILE__;
+ $actual = ($this->classLoader)('My\App\AutoloaderTest');
- $this->assertSame($expected, $actual);
+ $this->assertSame(normalize_path(__FILE__), $actual);
}
public function testAddNamespaceMultiplePathsWorks(): void
@@ -187,13 +179,15 @@ public function testAddNamespaceMultiplePathsWorks(): void
],
]);
- $actual = ($this->classLoader)('My\App\App');
- $expected = APPPATH . 'Config' . DIRECTORY_SEPARATOR . 'App.php';
- $this->assertSame($expected, $actual);
+ $this->assertSame(
+ APPPATH . 'Config/App.php',
+ ($this->classLoader)('My\App\App')
+ );
- $actual = ($this->classLoader)('My\App\AutoloaderTest');
- $expected = __FILE__;
- $this->assertSame($expected, $actual);
+ $this->assertSame(
+ normalize_path(__FILE__),
+ ($this->classLoader)('My\App\AutoloaderTest')
+ );
}
public function testAddNamespaceStringToArray(): void
@@ -201,7 +195,7 @@ public function testAddNamespaceStringToArray(): void
$this->loader->addNamespace('App\Controllers', __DIR__);
$this->assertSame(
- __FILE__,
+ normalize_path(__FILE__),
($this->classLoader)('App\Controllers\AutoloaderTest')
);
}
@@ -220,7 +214,7 @@ public function testGetNamespaceGivesArray(): void
public function testRemoveNamespace(): void
{
$this->loader->addNamespace('My\App', __DIR__);
- $this->assertSame(__FILE__, ($this->classLoader)('My\App\AutoloaderTest'));
+ $this->assertSame(normalize_path(__FILE__), ($this->classLoader)('My\App\AutoloaderTest'));
$this->loader->removeNamespace('My\App');
$this->assertFalse(($this->classLoader)('My\App\AutoloaderTest'));
@@ -287,8 +281,7 @@ public function testFindsComposerRoutes(): void
$loader = new Autoloader();
$loader->initialize($config, $modules);
- $namespaces = $loader->getNamespace();
- $this->assertArrayHasKey('Laminas\\Escaper', $namespaces);
+ $this->assertArrayHasKey('Laminas\\Escaper', $loader->getNamespace());
}
public function testComposerNamespaceDoesNotOverwriteConfigAutoloadPsr4(): void
@@ -379,8 +372,7 @@ public function testFindsComposerRoutesWithComposerPathNotFound(): void
$loader->initialize($config, $modules);
rename(COMPOSER_PATH . '.backup', $composerPath);
- $namespaces = $loader->getNamespace();
- $this->assertArrayNotHasKey('Laminas\\Escaper', $namespaces);
+ $this->assertArrayNotHasKey('Laminas\\Escaper', $loader->getNamespace());
}
public function testAutoloaderLoadsNonClassFiles(): void
diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php
index 90580864fc47..1901445c0bfe 100644
--- a/tests/system/Autoloader/FileLocatorTest.php
+++ b/tests/system/Autoloader/FileLocatorTest.php
@@ -231,21 +231,14 @@ public function testListFilesSimple(): void
{
$files = $this->locator->listFiles('Config/');
- $expectedWin = APPPATH . 'Config\App.php';
- $expectedLin = APPPATH . 'Config/App.php';
- $this->assertTrue(in_array($expectedWin, $files, true) || in_array($expectedLin, $files, true));
+ $this->assertContains(APPPATH . 'Config/App.php', $files);
}
public function testListFilesDoesNotContainDirectories(): void
{
$files = $this->locator->listFiles('Config/');
- $directory = str_replace(
- '/',
- DIRECTORY_SEPARATOR,
- APPPATH . 'Config/Boot'
- );
- $this->assertNotContains($directory, $files);
+ $this->assertNotContains(APPPATH . 'Config/Boot', $files);
}
public function testListFilesWithFileAsInput(): void
diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php
index cb54efdd64d0..afe565b1f363 100644
--- a/tests/system/CLI/CLITest.php
+++ b/tests/system/CLI/CLITest.php
@@ -323,7 +323,7 @@ public function testWrite(): void
{
CLI::write('test');
- $expected = PHP_EOL . 'test' . PHP_EOL;
+ $expected = "\ntest\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -331,7 +331,7 @@ public function testWriteForeground(): void
{
CLI::write('test', 'red');
- $expected = "\033[0;31mtest\033[0m" . PHP_EOL;
+ $expected = "\033[0;31mtest\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -339,7 +339,7 @@ public function testWriteForegroundWithColorBefore(): void
{
CLI::write(CLI::color('green', 'green') . ' red', 'red');
- $expected = "\033[0;32mgreen\033[0m\033[0;31m red\033[0m" . PHP_EOL;
+ $expected = "\033[0;32mgreen\033[0m\033[0;31m red\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -347,7 +347,7 @@ public function testWriteForegroundWithColorAfter(): void
{
CLI::write('red ' . CLI::color('green', 'green'), 'red');
- $expected = "\033[0;31mred \033[0m\033[0;32mgreen\033[0m" . PHP_EOL;
+ $expected = "\033[0;31mred \033[0m\033[0;32mgreen\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -361,7 +361,7 @@ public function testWriteForegroundWithColorTwice(): void
'red'
);
- $expected = "\033[0;32mgreen\033[0m\033[0;31m red \033[0m\033[0;32mgreen\033[0m" . PHP_EOL;
+ $expected = "\033[0;32mgreen\033[0m\033[0;31m red \033[0m\033[0;32mgreen\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -369,7 +369,7 @@ public function testWriteBackground(): void
{
CLI::write('test', 'red', 'green');
- $expected = "\033[0;31m\033[42mtest\033[0m" . PHP_EOL;
+ $expected = "\033[0;31m\033[42mtest\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -378,7 +378,7 @@ public function testError(): void
CLI::error('test');
// red expected cuz stderr
- $expected = "\033[1;31mtest\033[0m" . PHP_EOL;
+ $expected = "\033[1;31mtest\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -386,7 +386,7 @@ public function testErrorForeground(): void
{
CLI::error('test', 'purple');
- $expected = "\033[0;35mtest\033[0m" . PHP_EOL;
+ $expected = "\033[0;35mtest\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -394,7 +394,7 @@ public function testErrorBackground(): void
{
CLI::error('test', 'purple', 'green');
- $expected = "\033[0;35m\033[42mtest\033[0m" . PHP_EOL;
+ $expected = "\033[0;35m\033[42mtest\033[0m\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -411,16 +411,16 @@ public function testShowProgress(): void
CLI::write('third.');
CLI::showProgress(1, 20);
- $expected = 'first.' . PHP_EOL .
- "[\033[32m#.........\033[0m] 5% Complete" . PHP_EOL .
- "\033[1A[\033[32m#####.....\033[0m] 50% Complete" . PHP_EOL .
- "\033[1A[\033[32m##########\033[0m] 100% Complete" . PHP_EOL .
- 'second.' . PHP_EOL .
- "[\033[32m#.........\033[0m] 5% Complete" . PHP_EOL .
- "\033[1A[\033[32m#####.....\033[0m] 50% Complete" . PHP_EOL .
- "\033[1A[\033[32m##########\033[0m] 100% Complete" . PHP_EOL .
- 'third.' . PHP_EOL .
- "[\033[32m#.........\033[0m] 5% Complete" . PHP_EOL;
+ $expected = "first.\n" .
+ "[\033[32m#.........\033[0m] 5% Complete\n" .
+ "\033[1A[\033[32m#####.....\033[0m] 50% Complete\n" .
+ "\033[1A[\033[32m##########\033[0m] 100% Complete\n" .
+ "second.\n" .
+ "[\033[32m#.........\033[0m] 5% Complete\n" .
+ "\033[1A[\033[32m#####.....\033[0m] 50% Complete\n" .
+ "\033[1A[\033[32m##########\033[0m] 100% Complete\n" .
+ "third.\n" .
+ "[\033[32m#.........\033[0m] 5% Complete\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -431,7 +431,7 @@ public function testShowProgressWithoutBar(): void
CLI::showProgress(false, 20);
CLI::showProgress(false, 20);
- $expected = 'first.' . PHP_EOL . "\007\007\007";
+ $expected = "first.\n\007\007\007";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}
@@ -439,16 +439,16 @@ public function testWrap(): void
{
$this->assertSame('', CLI::wrap(''));
$this->assertSame(
- '1234' . PHP_EOL . ' 5678' . PHP_EOL . ' 90' . PHP_EOL . ' abc' . PHP_EOL . ' de' . PHP_EOL . ' fghij' . PHP_EOL . ' 0987654321',
- CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', 5, 1)
+ "1234\n 5678\n 90\n abc\n de\n fghij\n 0987654321",
+ CLI::wrap("1234 5678 90\nabc de fghij\n0987654321", 5, 1)
);
$this->assertSame(
- '1234 5678 90' . PHP_EOL . ' abc de fghij' . PHP_EOL . ' 0987654321',
- CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', 999, 2)
+ "1234 5678 90\n abc de fghij\n 0987654321",
+ CLI::wrap("1234 5678 90\nabc de fghij\n0987654321", 999, 2)
);
$this->assertSame(
- '1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321',
- CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321')
+ "1234 5678 90\nabc de fghij\n0987654321",
+ CLI::wrap("1234 5678 90\nabc de fghij\n0987654321")
);
}
@@ -605,38 +605,38 @@ public static function provideTable(): iterable
[
$oneRow,
[],
- '+---+-----+' . PHP_EOL .
- '| 1 | bar |' . PHP_EOL .
- '+---+-----+' . PHP_EOL . PHP_EOL,
+ "+---+-----+\n" .
+ "| 1 | bar |\n" .
+ "+---+-----+\n\n",
],
[
$oneRow,
$head,
- '+----+-------+' . PHP_EOL .
- '| ID | Title |' . PHP_EOL .
- '+----+-------+' . PHP_EOL .
- '| 1 | bar |' . PHP_EOL .
- '+----+-------+' . PHP_EOL . PHP_EOL,
+ "+----+-------+\n" .
+ "| ID | Title |\n" .
+ "+----+-------+\n" .
+ "| 1 | bar |\n" .
+ "+----+-------+\n\n",
],
[
$manyRows,
[],
- '+---+-----------------+' . PHP_EOL .
- '| 1 | bar |' . PHP_EOL .
- '| 2 | bar * 2 |' . PHP_EOL .
- '| 3 | bar + bar + bar |' . PHP_EOL .
- '+---+-----------------+' . PHP_EOL . PHP_EOL,
+ "+---+-----------------+\n" .
+ "| 1 | bar |\n" .
+ "| 2 | bar * 2 |\n" .
+ "| 3 | bar + bar + bar |\n" .
+ "+---+-----------------+\n\n",
],
[
$manyRows,
$head,
- '+----+-----------------+' . PHP_EOL .
- '| ID | Title |' . PHP_EOL .
- '+----+-----------------+' . PHP_EOL .
- '| 1 | bar |' . PHP_EOL .
- '| 2 | bar * 2 |' . PHP_EOL .
- '| 3 | bar + bar + bar |' . PHP_EOL .
- '+----+-----------------+' . PHP_EOL . PHP_EOL,
+ "+----+-----------------+\n" .
+ "| ID | Title |\n" .
+ "+----+-----------------+\n" .
+ "| 1 | bar |\n" .
+ "| 2 | bar * 2 |\n" .
+ "| 3 | bar + bar + bar |\n" .
+ "+----+-----------------+\n\n",
],
// Multibyte letters
[
@@ -650,11 +650,11 @@ public static function provideTable(): iterable
'ID',
'タイトル',
],
- '+------+----------+' . PHP_EOL .
- '| ID | タイトル |' . PHP_EOL .
- '+------+----------+' . PHP_EOL .
- '| ほげ | bar |' . PHP_EOL .
- '+------+----------+' . PHP_EOL . PHP_EOL,
+ "+------+----------+\n" .
+ "| ID | タイトル |\n" .
+ "+------+----------+\n" .
+ "| ほげ | bar |\n" .
+ "+------+----------+\n\n",
],
];
}
diff --git a/tests/system/Commands/CellGeneratorTest.php b/tests/system/Commands/CellGeneratorTest.php
index 31ec6dc3921e..4b9b8a4ad50d 100644
--- a/tests/system/Commands/CellGeneratorTest.php
+++ b/tests/system/Commands/CellGeneratorTest.php
@@ -27,7 +27,7 @@ final class CellGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
- $dirName = APPPATH . DIRECTORY_SEPARATOR . 'Cells';
+ $dirName = APPPATH . '/Cells';
// remove dir
if (is_dir($dirName)) {
$files = array_diff(scandir($dirName), ['.', '..']);
diff --git a/tests/system/Commands/ClearDebugbarTest.php b/tests/system/Commands/ClearDebugbarTest.php
index b3c2de18c394..fcb392e49c51 100644
--- a/tests/system/Commands/ClearDebugbarTest.php
+++ b/tests/system/Commands/ClearDebugbarTest.php
@@ -37,7 +37,7 @@ protected function setUp(): void
protected function createDummyDebugbarJson(): void
{
$time = $this->time;
- $path = WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . "debugbar_{$time}.json";
+ $path = WRITEPATH . "debugbar/debugbar_{$time}.json";
// create 10 dummy debugbar json files
for ($i = 0; $i < 10; $i++) {
@@ -51,17 +51,17 @@ protected function createDummyDebugbarJson(): void
public function testClearDebugbarWorks(): void
{
// test clean debugbar dir
- $this->assertFileDoesNotExist(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . "debugbar_{$this->time}.json");
+ $this->assertFileDoesNotExist(WRITEPATH . "debugbar/debugbar_{$this->time}.json");
// test dir is now populated with json
$this->createDummyDebugbarJson();
- $this->assertFileExists(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . "debugbar_{$this->time}.json");
+ $this->assertFileExists(WRITEPATH . "debugbar/debugbar_{$this->time}.json");
command('debugbar:clear');
$result = $this->getStreamFilterBuffer();
- $this->assertFileDoesNotExist(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . "debugbar_{$this->time}.json");
- $this->assertFileExists(WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . 'index.html');
+ $this->assertFileDoesNotExist(WRITEPATH . "debugbar/debugbar_{$this->time}.json");
+ $this->assertFileExists(WRITEPATH . 'debugbar/index.html');
$this->assertStringContainsString('Debugbar cleared.', $result);
}
}
diff --git a/tests/system/Commands/ClearLogsTest.php b/tests/system/Commands/ClearLogsTest.php
index 28019d5d51f6..a1e19717deb2 100644
--- a/tests/system/Commands/ClearLogsTest.php
+++ b/tests/system/Commands/ClearLogsTest.php
@@ -39,7 +39,7 @@ protected function setUp(): void
protected function createDummyLogFiles(): void
{
$date = $this->date;
- $path = WRITEPATH . 'logs' . DIRECTORY_SEPARATOR . "log-{$date}.log";
+ $path = WRITEPATH . "logs/log-{$date}.log";
// create 10 dummy log files
for ($i = 0; $i < 10; $i++) {
@@ -54,17 +54,17 @@ protected function createDummyLogFiles(): void
public function testClearLogsWorks(): void
{
// test clean logs dir
- $this->assertFileDoesNotExist(WRITEPATH . 'logs' . DIRECTORY_SEPARATOR . "log-{$this->date}.log");
+ $this->assertFileDoesNotExist(WRITEPATH . "logs/log-{$this->date}.log");
// test dir is now populated with logs
$this->createDummyLogFiles();
- $this->assertFileExists(WRITEPATH . 'logs' . DIRECTORY_SEPARATOR . "log-{$this->date}.log");
+ $this->assertFileExists(WRITEPATH . "logs/log-{$this->date}.log");
command('logs:clear -force');
$result = $this->getStreamFilterBuffer();
- $this->assertFileDoesNotExist(WRITEPATH . 'logs' . DIRECTORY_SEPARATOR . "log-{$this->date}.log");
- $this->assertFileExists(WRITEPATH . 'logs' . DIRECTORY_SEPARATOR . 'index.html');
+ $this->assertFileDoesNotExist(WRITEPATH . "logs/log-{$this->date}.log");
+ $this->assertFileExists(WRITEPATH . 'logs/index.html');
$this->assertStringContainsString('Logs cleared.', $result);
}
}
diff --git a/tests/system/Commands/CommandGeneratorTest.php b/tests/system/Commands/CommandGeneratorTest.php
index d485d6e4f063..d1cbf529d222 100644
--- a/tests/system/Commands/CommandGeneratorTest.php
+++ b/tests/system/Commands/CommandGeneratorTest.php
@@ -28,7 +28,7 @@ final class CommandGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
$dir = dirname($file);
if (is_file($file)) {
diff --git a/tests/system/Commands/ConfigGeneratorTest.php b/tests/system/Commands/ConfigGeneratorTest.php
index ab4914914719..8cd9c1b7fe34 100644
--- a/tests/system/Commands/ConfigGeneratorTest.php
+++ b/tests/system/Commands/ConfigGeneratorTest.php
@@ -28,7 +28,7 @@ final class ConfigGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
if (is_file($file)) {
unlink($file);
}
diff --git a/tests/system/Commands/ControllerGeneratorTest.php b/tests/system/Commands/ControllerGeneratorTest.php
index dc8293bb3997..818fe7774bce 100644
--- a/tests/system/Commands/ControllerGeneratorTest.php
+++ b/tests/system/Commands/ControllerGeneratorTest.php
@@ -28,7 +28,7 @@ final class ControllerGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
if (is_file($file)) {
unlink($file);
}
diff --git a/tests/system/Commands/EntityGeneratorTest.php b/tests/system/Commands/EntityGeneratorTest.php
index 1e764add9cec..54f832fecb3d 100644
--- a/tests/system/Commands/EntityGeneratorTest.php
+++ b/tests/system/Commands/EntityGeneratorTest.php
@@ -28,7 +28,7 @@ final class EntityGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
$dir = dirname($file);
if (is_file($file)) {
unlink($file);
diff --git a/tests/system/Commands/FilterGeneratorTest.php b/tests/system/Commands/FilterGeneratorTest.php
index b336387d3ab4..d92a0c1cde21 100644
--- a/tests/system/Commands/FilterGeneratorTest.php
+++ b/tests/system/Commands/FilterGeneratorTest.php
@@ -28,7 +28,7 @@ final class FilterGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
if (is_file($file)) {
unlink($file);
}
diff --git a/tests/system/Commands/MigrationGeneratorTest.php b/tests/system/Commands/MigrationGeneratorTest.php
index 0f999d638789..d11d65028e04 100644
--- a/tests/system/Commands/MigrationGeneratorTest.php
+++ b/tests/system/Commands/MigrationGeneratorTest.php
@@ -28,7 +28,7 @@ final class MigrationGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
if (is_file($file)) {
unlink($file);
}
diff --git a/tests/system/Commands/MigrationIntegrationTest.php b/tests/system/Commands/MigrationIntegrationTest.php
index 14b66ccb920a..6333f06bb000 100644
--- a/tests/system/Commands/MigrationIntegrationTest.php
+++ b/tests/system/Commands/MigrationIntegrationTest.php
@@ -52,7 +52,7 @@ protected function tearDown(): void
parent::tearDown();
if (is_file($this->migrationFileTo)) {
- @unlink($this->migrationFileTo);
+ unlink($this->migrationFileTo);
}
}
diff --git a/tests/system/Commands/ModelGeneratorTest.php b/tests/system/Commands/ModelGeneratorTest.php
index 65596958606c..336603806597 100644
--- a/tests/system/Commands/ModelGeneratorTest.php
+++ b/tests/system/Commands/ModelGeneratorTest.php
@@ -30,7 +30,7 @@ protected function tearDown(): void
parent::tearDown();
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
if (is_file($file)) {
unlink($file);
diff --git a/tests/system/Commands/ScaffoldGeneratorTest.php b/tests/system/Commands/ScaffoldGeneratorTest.php
index fe99f2c38ccd..795d79ea1c58 100644
--- a/tests/system/Commands/ScaffoldGeneratorTest.php
+++ b/tests/system/Commands/ScaffoldGeneratorTest.php
@@ -48,10 +48,10 @@ public function testCreateComponentProducesManyFiles(): void
{
command('make:scaffold people');
- $dir = '\\' . DIRECTORY_SEPARATOR;
+ $dir = '\\/';
$migration = "APPPATH{$dir}Database{$dir}Migrations{$dir}(.*)\\.php";
preg_match('/' . $migration . '/u', $this->getStreamFilterBuffer(), $matches);
- $matches[0] = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, $matches[0]);
+ $matches[0] = str_replace('APPPATH/', APPPATH, $matches[0]);
// Files check
$this->assertStringContainsString('File created: ', $this->getStreamFilterBuffer());
@@ -71,10 +71,10 @@ public function testCreateComponentWithManyOptions(): void
{
command('make:scaffold user -restful -return entity');
- $dir = '\\' . DIRECTORY_SEPARATOR;
+ $dir = '\\/';
$migration = "APPPATH{$dir}Database{$dir}Migrations{$dir}(.*)\\.php";
preg_match('/' . $migration . '/u', $this->getStreamFilterBuffer(), $matches);
- $matches[0] = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, $matches[0]);
+ $matches[0] = str_replace('APPPATH/', APPPATH, $matches[0]);
// Files check
$this->assertStringContainsString('File created: ', $this->getStreamFilterBuffer());
@@ -100,10 +100,10 @@ public function testCreateComponentWithOptionSuffix(): void
{
command('make:scaffold order -suffix');
- $dir = '\\' . DIRECTORY_SEPARATOR;
+ $dir = '\\/';
$migration = "APPPATH{$dir}Database{$dir}Migrations{$dir}(.*)\\.php";
preg_match('/' . $migration . '/u', $this->getStreamFilterBuffer(), $matches);
- $matches[0] = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, $matches[0]);
+ $matches[0] = str_replace('APPPATH/', APPPATH, $matches[0]);
// Files check
$this->assertStringContainsString('File created: ', $this->getStreamFilterBuffer());
@@ -129,10 +129,10 @@ public function testCreateComponentWithOptionForce(): void
command('make:scaffold fixer -bare -force');
- $dir = '\\' . DIRECTORY_SEPARATOR;
+ $dir = '\\/';
$migration = "APPPATH{$dir}Database{$dir}Migrations{$dir}(.*)\\.php";
preg_match('/' . $migration . '/u', $this->getStreamFilterBuffer(), $matches);
- $matches[0] = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, $matches[0]);
+ $matches[0] = str_replace('APPPATH/', APPPATH, $matches[0]);
// Files check
$this->assertStringContainsString('File created: ', $this->getStreamFilterBuffer());
@@ -156,10 +156,10 @@ public function testCreateComponentWithOptionNamespace(): void
{
command('make:scaffold product -namespace App');
- $dir = '\\' . DIRECTORY_SEPARATOR;
+ $dir = '\\/';
$migration = "APPPATH{$dir}Database{$dir}Migrations{$dir}(.*)\\.php";
preg_match('/' . $migration . '/u', $this->getStreamFilterBuffer(), $matches);
- $matches[0] = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, $matches[0]);
+ $matches[0] = str_replace('APPPATH/', APPPATH, $matches[0]);
// Files check
$this->assertStringContainsString('File created: ', $this->getStreamFilterBuffer());
diff --git a/tests/system/Commands/SeederGeneratorTest.php b/tests/system/Commands/SeederGeneratorTest.php
index b8f504489c5b..4d4e8dab49bd 100644
--- a/tests/system/Commands/SeederGeneratorTest.php
+++ b/tests/system/Commands/SeederGeneratorTest.php
@@ -30,7 +30,7 @@ protected function tearDown(): void
parent::tearDown();
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
if (is_file($file)) {
unlink($file);
}
diff --git a/tests/system/Commands/TestGeneratorTest.php b/tests/system/Commands/TestGeneratorTest.php
index b449afd76f05..7c4aac18e336 100644
--- a/tests/system/Commands/TestGeneratorTest.php
+++ b/tests/system/Commands/TestGeneratorTest.php
@@ -28,7 +28,7 @@ final class TestGeneratorTest extends CIUnitTestCase
protected function tearDown(): void
{
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('ROOTPATH' . DIRECTORY_SEPARATOR, ROOTPATH, trim(substr($result, 14)));
+ $file = str_replace('ROOTPATH/', ROOTPATH, trim(substr($result, 14)));
$dir = dirname($file);
if (is_file($file)) {
unlink($file);
diff --git a/tests/system/Commands/ValidationGeneratorTest.php b/tests/system/Commands/ValidationGeneratorTest.php
index 0bcbcdec12e7..768d52eef983 100644
--- a/tests/system/Commands/ValidationGeneratorTest.php
+++ b/tests/system/Commands/ValidationGeneratorTest.php
@@ -30,7 +30,7 @@ protected function tearDown(): void
parent::tearDown();
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer());
- $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
+ $file = str_replace('APPPATH/', APPPATH, trim(substr($result, 14)));
$dir = dirname($file);
if (is_file($file)) {
unlink($file);
diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php
index f2c81684b623..5b46f5a2f2b6 100644
--- a/tests/system/CommonFunctionsTest.php
+++ b/tests/system/CommonFunctionsTest.php
@@ -43,7 +43,6 @@
use Exception;
use Kint;
use PHPUnit\Framework\Attributes\BackupGlobals;
-use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\PreserveGlobalState;
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
@@ -673,44 +672,6 @@ public function testForceHttpsWithBaseUrlSubFolder(): void
}
}
- /**
- * @param mixed $input
- * @param mixed $expected
- */
- #[DataProvider('provideCleanPathActuallyCleaningThePaths')]
- public function testCleanPathActuallyCleaningThePaths($input, $expected): void
- {
- $this->assertSame($expected, clean_path($input));
- }
-
- public static function provideCleanPathActuallyCleaningThePaths(): iterable
- {
- $ds = DIRECTORY_SEPARATOR;
-
- return [
- [
- ROOTPATH . 'spark',
- 'ROOTPATH' . $ds . 'spark',
- ],
- [
- APPPATH . 'Config' . $ds . 'App.php',
- 'APPPATH' . $ds . 'Config' . $ds . 'App.php',
- ],
- [
- SYSTEMPATH . 'CodeIgniter.php',
- 'SYSTEMPATH' . $ds . 'CodeIgniter.php',
- ],
- [
- VENDORPATH . 'autoload.php',
- 'VENDORPATH' . $ds . 'autoload.php',
- ],
- [
- FCPATH . 'index.php',
- 'FCPATH' . $ds . 'index.php',
- ],
- ];
- }
-
public function testIsCli(): void
{
$this->assertIsBool(is_cli());
diff --git a/tests/system/CommonHelperTest.php b/tests/system/CommonHelperTest.php
index 86ba03a8b25e..f131d10f077a 100644
--- a/tests/system/CommonHelperTest.php
+++ b/tests/system/CommonHelperTest.php
@@ -30,8 +30,8 @@
final class CommonHelperTest extends CIUnitTestCase
{
private array $dummyHelpers = [
- APPPATH . 'Helpers' . DIRECTORY_SEPARATOR . 'foobarbaz_helper.php',
- SYSTEMPATH . 'Helpers' . DIRECTORY_SEPARATOR . 'foobarbaz_helper.php',
+ APPPATH . 'Helpers/foobarbaz_helper.php',
+ SYSTEMPATH . 'Helpers/foobarbaz_helper.php',
];
protected function setUp(): void
@@ -56,7 +56,7 @@ private function createDummyHelpers(): void
if (! function_exists('foo_bar_baz')) {
function foo_bar_baz(): string
{
- return __FILE__;
+ return normalize_path(__FILE__);
}
}
@@ -142,7 +142,7 @@ public function testHelperLoadsAppHelperFirst(): void
if (! function_exists('foo_bar_baz')) {
function foo_bar_baz(): string
{
- return __FILE__;
+ return normalize_path(__FILE__);
}
}
diff --git a/tests/system/Config/DotEnvTest.php b/tests/system/Config/DotEnvTest.php
index 6fd287be6ad5..f96e7296e916 100644
--- a/tests/system/Config/DotEnvTest.php
+++ b/tests/system/Config/DotEnvTest.php
@@ -45,7 +45,7 @@ protected function setUp(): void
vfsStream::copyFromFileSystem($path, $this->root);
$file = 'unreadable.env';
- $path = rtrim($this->fixturesFolder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file;
+ $path = rtrim($this->fixturesFolder, '\\/') . '/' . $file;
chmod($path, 0644);
}
@@ -132,7 +132,7 @@ public function testCommentedLoadsVars(): void
public function testLoadsUnreadableFile(): void
{
$file = 'unreadable.env';
- $path = rtrim($this->fixturesFolder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file;
+ $path = rtrim($this->fixturesFolder, '\\/') . '/' . $file;
chmod($path, 0000);
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("The .env file is not readable: {$path}");
diff --git a/tests/system/Database/Migrations/MigrationRunnerTest.php b/tests/system/Database/Migrations/MigrationRunnerTest.php
index 0ecd2ca0b051..63bb9334457e 100644
--- a/tests/system/Database/Migrations/MigrationRunnerTest.php
+++ b/tests/system/Database/Migrations/MigrationRunnerTest.php
@@ -259,7 +259,7 @@ public function testFindMigrationsSuccessTimestamp(): void
$mig1 = (object) [
'version' => '2018-01-24-102301',
'name' => 'Some_migration',
- 'path' => realpath(TESTPATH . '_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php'),
+ 'path' => _realpath(TESTPATH . '_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php'),
'class' => Migration_some_migration::class,
'namespace' => 'Tests\Support\MigrationTestMigrations',
];
@@ -268,7 +268,7 @@ public function testFindMigrationsSuccessTimestamp(): void
$mig2 = (object) [
'version' => '2018-01-24-102302',
'name' => 'Another_migration',
- 'path' => realpath(TESTPATH . '_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102302_Another_migration.php'),
+ 'path' => _realpath(TESTPATH . '_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102302_Another_migration.php'),
'class' => Migration_another_migration::class,
'namespace' => 'Tests\Support\MigrationTestMigrations',
'uid' => '20180124102302Tests\Support\MigrationTestMigrations\Database\Migrations\Migration_another_migration',
@@ -473,6 +473,8 @@ public function testMigrationUsesSameConnectionAsMigrationRunner(): void
$this->assertSame('foo', $tables[1]);
if (is_file($config['database'])) {
+ // In Windows fail https://bugs.php.net/bug.php?id=78930
+ $database->close();
unlink($config['database']);
}
}
diff --git a/tests/system/Files/FileCollectionTest.php b/tests/system/Files/FileCollectionTest.php
index 44a1acf54dab..bb390b571b31 100644
--- a/tests/system/Files/FileCollectionTest.php
+++ b/tests/system/Files/FileCollectionTest.php
@@ -65,14 +65,18 @@ public function testResolveDirectoryFile(): void
public function testResolveDirectorySymlink(): void
{
// Create a symlink to test
- $link = sys_get_temp_dir() . DIRECTORY_SEPARATOR . bin2hex(random_bytes(4));
+ $link = WRITEPATH . bin2hex(random_bytes(4));
symlink($this->directory, $link);
$method = $this->getPrivateMethodInvoker(FileCollection::class, 'resolveDirectory');
$this->assertSame($this->directory, $method($link));
- unlink($link);
+ if (is_windows() && is_dir($link)) {
+ rmdir($link);
+ } else {
+ unlink($link);
+ }
}
public function testResolveFileFile(): void
@@ -85,7 +89,7 @@ public function testResolveFileFile(): void
public function testResolveFileSymlink(): void
{
// Create a symlink to test
- $link = sys_get_temp_dir() . DIRECTORY_SEPARATOR . bin2hex(random_bytes(4));
+ $link = WRITEPATH . bin2hex(random_bytes(4));
symlink($this->file, $link);
$method = $this->getPrivateMethodInvoker(FileCollection::class, 'resolveFile');
diff --git a/tests/system/HTTP/Files/FileMovingTest.php b/tests/system/HTTP/Files/FileMovingTest.php
index 9624ecd78a06..47866d7d0e8a 100644
--- a/tests/system/HTTP/Files/FileMovingTest.php
+++ b/tests/system/HTTP/Files/FileMovingTest.php
@@ -209,7 +209,7 @@ public function testStore(): void
$file = $collection->getFile('userfile1');
$this->assertInstanceOf(UploadedFile::class, $file);
-
+ // var_dump($destination, $file->getName(), is_dir($destination)); exit;
$path = $file->store($destination, $file->getName());
$this->assertSame($destination . '/fileA.txt', $path);
diff --git a/tests/system/Helpers/FilesystemHelperTest.php b/tests/system/Helpers/FilesystemHelperTest.php
index a8ee76d6ab09..9d43b4abee69 100644
--- a/tests/system/Helpers/FilesystemHelperTest.php
+++ b/tests/system/Helpers/FilesystemHelperTest.php
@@ -55,15 +55,15 @@ public function testDirectoryMapDefaults(): void
$this->assertTrue(function_exists('directory_map'));
$expected = [
- 'foo' . DIRECTORY_SEPARATOR => [
+ 'foo/' => [
'bar',
'baz',
],
- 'boo' . DIRECTORY_SEPARATOR => [
+ 'boo/' => [
'far',
'faz',
],
- 'AnEmptyFolder' . DIRECTORY_SEPARATOR => [],
+ 'AnEmptyFolder/' => [],
'simpleFile',
];
@@ -78,15 +78,15 @@ public function testDirectoryMapShowsHiddenFiles(): void
$this->assertTrue(function_exists('directory_map'));
$expected = [
- 'foo' . DIRECTORY_SEPARATOR => [
+ 'foo/' => [
'bar',
'baz',
],
- 'boo' . DIRECTORY_SEPARATOR => [
+ 'boo/' => [
'far',
'faz',
],
- 'AnEmptyFolder' . DIRECTORY_SEPARATOR => [],
+ 'AnEmptyFolder/' => [],
'simpleFile',
'.hidden',
];
@@ -102,9 +102,9 @@ public function testDirectoryMapLimitsRecursion(): void
$this->assertTrue(function_exists('directory_map'));
$expected = [
- 'foo' . DIRECTORY_SEPARATOR,
- 'boo' . DIRECTORY_SEPARATOR,
- 'AnEmptyFolder' . DIRECTORY_SEPARATOR,
+ 'foo/',
+ 'boo/',
+ 'AnEmptyFolder/',
'simpleFile',
'.hidden',
];
@@ -128,7 +128,7 @@ public function testDirectoryMirror(): void
$this->structure['foo']['bam'] = ['zab' => 'A deep file'];
vfsStream::setup('root', null, $this->structure);
- $root = rtrim(vfsStream::url('root') . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $root = rtrim(vfsStream::url('root') . '/') . '/';
directory_mirror($root . 'foo', $root . 'boo');
@@ -145,7 +145,7 @@ public function testDirectoryMirrorOverwrites(): void
$this->structure['foo']['faz'] = 'are belong to us';
vfsStream::setup('root', null, $this->structure);
- $root = rtrim(vfsStream::url('root') . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $root = rtrim(vfsStream::url('root') . '/') . '/';
directory_mirror($root . 'foo', $root . 'boo', true);
$result = file_get_contents($root . 'boo/faz');
@@ -162,7 +162,7 @@ public function testDirectoryMirrorNotOverwrites(): void
$this->structure['foo']['faz'] = 'are belong to us';
vfsStream::setup('root', null, $this->structure);
- $root = rtrim(vfsStream::url('root') . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $root = rtrim(vfsStream::url('root') . '/') . '/';
directory_mirror($root . 'foo', $root . 'boo', false);
$result = file_get_contents($root . 'boo/faz');
@@ -183,7 +183,7 @@ public function testDirectoryMirrorSkipExistingFolder(): void
],
];
vfsStream::setup('root', null, $this->structure);
- $root = rtrim(vfsStream::url('root') . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ $root = rtrim(vfsStream::url('root') . '/') . '/';
// skips the existing folder
directory_mirror($root . 'src', $root . 'dest');
@@ -380,14 +380,14 @@ public function testGetFilenamesWithFullSource(): void
$vfs = vfsStream::setup('root', null, $this->structure);
$expected = [
- $vfs->url() . DIRECTORY_SEPARATOR . 'AnEmptyFolder',
- $vfs->url() . DIRECTORY_SEPARATOR . 'boo',
- $vfs->url() . DIRECTORY_SEPARATOR . 'boo/far',
- $vfs->url() . DIRECTORY_SEPARATOR . 'boo/faz',
- $vfs->url() . DIRECTORY_SEPARATOR . 'foo',
- $vfs->url() . DIRECTORY_SEPARATOR . 'foo/bar',
- $vfs->url() . DIRECTORY_SEPARATOR . 'foo/baz',
- $vfs->url() . DIRECTORY_SEPARATOR . 'simpleFile',
+ $vfs->url() . '/AnEmptyFolder',
+ $vfs->url() . '/boo',
+ $vfs->url() . '/boo/far',
+ $vfs->url() . '/boo/faz',
+ $vfs->url() . '/foo',
+ $vfs->url() . '/foo/bar',
+ $vfs->url() . '/foo/baz',
+ $vfs->url() . '/simpleFile',
];
$this->assertSame($expected, get_filenames($vfs->url(), true));
@@ -440,14 +440,14 @@ public function testGetDirFileInfo(): void
'server_path' => $file1,
'size' => $info1['size'],
'date' => $info1['date'],
- 'relative_path' => realpath(__DIR__ . '/../../_support/Files/baker'),
+ 'relative_path' => _realpath(__DIR__ . '/../../_support/Files/baker'),
],
'fig_3.php.txt' => [
'name' => 'fig_3.php.txt',
'server_path' => $file2,
'size' => $info2['size'],
'date' => $info2['date'],
- 'relative_path' => realpath(__DIR__ . '/../../_support/Files/baker'),
+ 'relative_path' => _realpath(__DIR__ . '/../../_support/Files/baker'),
],
];
@@ -505,6 +505,10 @@ public function testGetFileInfoCustom(): void
public function testGetFileInfoPerms(): void
{
+ if (is_windows()) {
+ $this->markTestSkipped('Windows works differently with access rights');
+ }
+
$file = SUPPORTPATH . 'Files/baker/banana.php';
$expected = 0664;
chmod($file, $expected);
diff --git a/tests/system/Test/BootstrapFCPATHTest.php b/tests/system/Test/BootstrapFCPATHTest.php
index d58bb847360d..e254a169ca43 100644
--- a/tests/system/Test/BootstrapFCPATHTest.php
+++ b/tests/system/Test/BootstrapFCPATHTest.php
@@ -52,14 +52,12 @@ protected function tearDown(): void
public function testSetFCPATH(): void
{
- $result1 = $this->readOutput($this->file1);
- $correctPath = $this->correctFCPATH();
- $this->assertSame($correctPath, $result1);
+ $this->assertSame($this->correctFCPATH(), $this->readOutput($this->file1));
}
private function correctFCPATH()
{
- return realpath(__DIR__ . '/../../../public') . DIRECTORY_SEPARATOR;
+ return _realpath(__DIR__ . '/../../../public') . '/';
}
private function buildDirectories(): void
@@ -91,15 +89,15 @@ private function deleteFiles(): void
private function fileContents()
{
$fileContents = '';
- $fileContents .= 'currentDir . "' . '/../../../');" . PHP_EOL;
- $fileContents .= "define('CONFIGPATH', '" . $this->currentDir . "' . '/../../../app/Config/');" . PHP_EOL;
- $fileContents .= "define('PUBLICPATH', '" . $this->currentDir . "' . '/../../../public/');" . PHP_EOL;
- $fileContents .= "include_once '" . $this->currentDir . "' . '/../../../vendor/autoload.php';" . PHP_EOL;
- $fileContents .= "include_once '" . $this->currentDir . "' . '/../../../system/Test/bootstrap.php';" . PHP_EOL;
- $fileContents .= '// return value of FCPATH' . PHP_EOL;
-
- return $fileContents . ('echo FCPATH;' . PHP_EOL);
+ $fileContents .= "currentDir . "' . '/../../../');\n";
+ $fileContents .= "define('CONFIGPATH', '" . $this->currentDir . "' . '/../../../app/Config/');\n";
+ $fileContents .= "define('PUBLICPATH', '" . $this->currentDir . "' . '/../../../public/');\n";
+ $fileContents .= "include_once '" . $this->currentDir . "' . '/../../../vendor/autoload.php';\n";
+ $fileContents .= "include_once '" . $this->currentDir . "' . '/../../../system/Test/bootstrap.php';\n";
+ $fileContents .= "// return value of FCPATH\n";
+
+ return $fileContents . ("echo FCPATH;\n");
}
private function readOutput(string $file)
diff --git a/tests/system/Test/TestCaseTest.php b/tests/system/Test/TestCaseTest.php
index 6905d825533a..1387f0840e1d 100644
--- a/tests/system/Test/TestCaseTest.php
+++ b/tests/system/Test/TestCaseTest.php
@@ -70,7 +70,7 @@ public function testEventTriggering(): void
public function testStreamFilter(): void
{
CLI::write('first.');
- $expected = PHP_EOL . 'first.' . PHP_EOL;
+ $expected = "\nfirst.\n";
$this->assertSame($expected, $this->getStreamFilterBuffer());
}