diff --git a/4dev/tests/CoreLibsGetDotEnvTest.php b/4dev/tests/CoreLibsGetDotEnvTest.php
new file mode 100644
index 00000000..285e19ef
--- /dev/null
+++ b/4dev/tests/CoreLibsGetDotEnvTest.php
@@ -0,0 +1,162 @@
+ 'A',
+ 'OTHER' => 'B IS B',
+ 'Complex' => 'A B \"D is F',
+ 'HAS_SPACE' => 'ABC',
+ 'HAS_COMMENT_QUOTES_SPACE' => 'Comment at end with quotes and space',
+ 'HAS_COMMENT_QUOTES_NO_SPACE' => 'Comment at end with quotes no space',
+ 'HAS_COMMENT_NO_QUOTES_SPACE' => 'Comment at end no quotes and space',
+ 'HAS_COMMENT_NO_QUOTES_NO_SPACE' => 'Comment at end no quotes no space',
+ 'COMMENT_IN_TEXT_QUOTES' => 'Foo bar # comment in here',
+ 'FAILURE' => 'ABC',
+ 'SIMPLEBOX' => 'A B C',
+ 'TITLE' => '1',
+ 'FOO' => '1.2',
+ 'SOME.TEST' => 'Test Var',
+ 'SOME.LIVE' => 'Live Var',
+ 'A_TEST1' => 'foo',
+ 'A_TEST2' => '${TEST1:-bar}',
+ 'A_TEST3' => '${TEST4:-bar}',
+ 'A_TEST5' => 'null',
+ 'A_TEST6' => '${TEST5-bar}',
+ 'A_TEST7' => '${TEST6:-bar}',
+ 'B_TEST1' => 'foo',
+ 'B_TEST2' => '${TEST1:=bar}',
+ 'B_TEST3' => '${TEST4:=bar}',
+ 'B_TEST5' => 'null',
+ 'B_TEST6' => '${TEST5=bar}',
+ 'B_TEST7' => '${TEST6=bar}',
+ 'Test' => 'A',
+ 'TEST' => 'B',
+ 'LINE' => "ABC\nDEF",
+ 'OTHERLINE' => "ABC\nAF\"ASFASDF\nMORESHIT",
+ 'SUPERLINE' => '',
+ '__FOO_BAR_1' => 'b',
+ '__FOOFOO' => 'f ',
+ 123123 => 'number',
+ 'EMPTY' => '',
+ ];
+ // 0: folder relative to test folder, if unset __DIR__
+ // 1: file, if unset .env
+ // 2: status to be returned
+ // 3: _ENV file content to be set
+ // 4: override chmod as octect in string
+ return [
+ 'default' => [
+ 'folder' => null,
+ 'file' => null,
+ 'status' => 3,
+ 'content' => [],
+ 'chmod' => null,
+ ],
+ 'cannot open file' => [
+ 'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
+ 'file' => 'cannot_read.env',
+ 'status' => 2,
+ 'content' => [],
+ 'chmod' => '000',
+ ],
+ 'empty file' => [
+ 'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
+ 'file' => 'empty.env',
+ 'status' => 1,
+ 'content' => [],
+ 'chmod' => null,
+ ],
+ 'override all' => [
+ 'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
+ 'file' => 'test.env',
+ 'status' => 0,
+ 'content' => $dot_env_content,
+ 'chmod' => null,
+ ],
+ 'override directory' => [
+ 'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
+ 'file' => null,
+ 'status' => 0,
+ 'content' => $dot_env_content,
+ 'chmod' => null,
+ ],
+ ];
+ }
+
+ /**
+ * test read .env file
+ *
+ * @covers ::readEnvFile
+ * @dataProvider envFileProvider
+ * @testdox Read _ENV file from $folder / $file with expected status: $expected_status and chmod $chmod [$_dataName]
+ *
+ * @param string|null $folder
+ * @param string|null $file
+ * @param int $expected_status
+ * @param array $expected_env
+ * @param string|null $chmod
+ * @return void
+ */
+ public function testReadEnvFile(
+ ?string $folder,
+ ?string $file,
+ int $expected_status,
+ array $expected_env,
+ ?string $chmod
+ ): void {
+ // if we have file + chmod set
+ $old_chmod = null;
+ if (
+ is_file($folder . DIRECTORY_SEPARATOR . $file) &&
+ !empty($chmod)
+ ) {
+ // get the old permissions
+ $old_chmod = fileperms($folder . DIRECTORY_SEPARATOR . $file);
+ chmod($folder . DIRECTORY_SEPARATOR . $file, octdec($chmod));
+ }
+ if ($folder !== null && $file !== null) {
+ $status = DotEnv::readEnvFile($folder, $file);
+ } elseif ($folder !== null) {
+ $status = DotEnv::readEnvFile($folder);
+ } else {
+ $status = DotEnv::readEnvFile();
+ }
+ $this->assertEquals(
+ $status,
+ $expected_status,
+ 'Assert returned status equal'
+ );
+ // now assert read data
+ $this->assertEquals(
+ $_ENV,
+ $expected_env,
+ 'Assert _ENV correct'
+ );
+ // if we have file and chmod unset
+ if ($old_chmod !== null) {
+ chmod($folder . DIRECTORY_SEPARATOR . $file, $old_chmod);
+ }
+ }
+}
+
+// __END__
diff --git a/4dev/tests/dotenv/.env b/4dev/tests/dotenv/.env
new file mode 120000
index 00000000..a67af1f7
--- /dev/null
+++ b/4dev/tests/dotenv/.env
@@ -0,0 +1 @@
+test.env
\ No newline at end of file
diff --git a/4dev/tests/dotenv/cannot_read.env b/4dev/tests/dotenv/cannot_read.env
new file mode 100644
index 00000000..e69de29b
diff --git a/4dev/tests/dotenv/empty.env b/4dev/tests/dotenv/empty.env
new file mode 100644
index 00000000..e69de29b
diff --git a/4dev/tests/dotenv/test.env b/4dev/tests/dotenv/test.env
new file mode 100644
index 00000000..46d34565
--- /dev/null
+++ b/4dev/tests/dotenv/test.env
@@ -0,0 +1,49 @@
+# enviroment file
+SOMETHING=A
+OTHER="B IS B"
+Complex="A B \"D is F"
+# COMMENT
+HAS_SPACE= "ABC";
+# COMMENT AT END
+HAS_COMMENT_QUOTES_SPACE="Comment at end with quotes and space" # Comment QE
+HAS_COMMENT_QUOTES_NO_SPACE="Comment at end with quotes no space"# Comment QES
+HAS_COMMENT_NO_QUOTES_SPACE=Comment at end no quotes and space # Comment NQE
+HAS_COMMENT_NO_QUOTES_NO_SPACE=Comment at end no quotes no space# Comment NQES
+COMMENT_IN_TEXT_QUOTES="Foo bar # comment in here"
+FAILURE = ABC
+SIMPLEBOX= A B C
+TITLE=1
+FOO=1.2
+SOME.TEST=Test Var
+SOME.LIVE=Live Var
+# VAR TESTS -
+A_TEST1 = foo
+A_TEST2 = ${TEST1:-bar} # TEST1 is set so the value of TEST2 = foo
+A_TEST3 = ${TEST4:-bar} # TEST4 is not set so the value of TEST3 = bar
+A_TEST5 = null
+A_TEST6 = ${TEST5-bar} # TEST5 is set but empty so the value of TEST6 = null
+A_TEST7 = ${TEST6:-bar} # TEST5 is set and empty so the value of TEST7 = bar
+# VAR TESTS =
+B_TEST1 = foo
+B_TEST2 = ${TEST1:=bar} # TEST1 is set so the value of TEST2 = foo
+B_TEST3 = ${TEST4:=bar} # TEST4 is not set so the value of TEST3 = bar and TEST4 = bar
+B_TEST5 = null
+B_TEST6 = ${TEST5=bar} # TEST5 is set but emtpy so the value of TEST6 = null
+B_TEST7 = ${TEST6=bar} # TEST5 is set and empty so the value of TEST7 = bar and TEST5 = bar
+# VAR TEST END
+Test="A"
+TEST="B"
+TEST="D"
+LINE="ABC
+DEF"
+OTHERLINE="ABC
+AF\"ASFASDF
+MORESHIT"
+SUPERLINE=
+"asfasfasf"
+ __FOO_BAR_1 = b
+ __FOOFOO = f
+123123=number
+EMPTY=
+= flase
+asfasdf
diff --git a/www/admin/class_test.readenvfile.php b/www/admin/class_test.readenvfile.php
index ee5b277e..c60ed033 100644
--- a/www/admin/class_test.readenvfile.php
+++ b/www/admin/class_test.readenvfile.php
@@ -40,6 +40,9 @@ print '
' . $PAGE_NAME . '
';
print "ALREADY from config.php: " . \CoreLibs\Debug\Support::printAr($_ENV) . "
";
// test .env in local
+$status = \CoreLibs\Get\DotEnv::readEnvFile('.', 'test.env');
+print "test.env: STATUS: " . $status . "
";
+print "AFTER reading test.env file: " . \CoreLibs\Debug\Support::printAr($_ENV) . "
";
// error message
print $log->printErrorMsg();
diff --git a/www/admin/test.env b/www/admin/test.env
new file mode 120000
index 00000000..4988714a
--- /dev/null
+++ b/www/admin/test.env
@@ -0,0 +1 @@
+../../4dev/tests/dotenv/test.env
\ No newline at end of file
diff --git a/www/configs/config.php b/www/configs/config.php
index c0e08ed6..df7f3b95 100644
--- a/www/configs/config.php
+++ b/www/configs/config.php
@@ -50,7 +50,7 @@ for (
is_file($__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php')
) {
// load enviorment file if it exists
- \CoreLibs\Get\ReadEnvFile::readEnvFile(
+ \CoreLibs\Get\DotEnv::readEnvFile(
$__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH
);
// load master config file that loads all other config files
diff --git a/www/lib/CoreLibs/Get/DotEnv.php b/www/lib/CoreLibs/Get/DotEnv.php
new file mode 100644
index 00000000..8572b141
--- /dev/null
+++ b/www/lib/CoreLibs/Get/DotEnv.php
@@ -0,0 +1,106 @@
+ abort
+ if (!is_file($env_file_target)) {
+ $status = 3;
+ return $status;
+ }
+ // cannot open file -> abort
+ if (!is_readable($env_file_target)) {
+ $status = 2;
+ return $status;
+ }
+ // open file
+ if (($fp = fopen($env_file_target, 'r')) === false) {
+ $status = 2;
+ return $status;
+ }
+ // set to readable but not yet any data loaded
+ $status = 1;
+ $block = false;
+ $var = '';
+ while ($line = fgets($fp)) {
+ // main match for variable = value part
+ if (preg_match("/^\s*([\w_.]+)\s*=\s*((\"?).*)/", $line, $matches)) {
+ $var = $matches[1];
+ $value = $matches[2];
+ $quotes = $matches[3];
+ // write only if env is not set yet, and write only the first time
+ if (empty($_ENV[$var])) {
+ if (!empty($quotes)) {
+ // match greedy for first to last so we move any " if there are
+ if (preg_match('/^"(.*[^\\\])"/U', $value, $matches)) {
+ $value = $matches[1];
+ } else {
+ // this is a multi line
+ $block = true;
+ // first " in string remove
+ // add removed new line back because this is a multi line
+ $value = ltrim($value, '"') . PHP_EOL;
+ }
+ } else {
+ // strip any quotes at end for unquoted single line
+ // an right hand spaces are removed too
+ $value = false !== ($pos = strpos($value, self::COMMENT_CHAR)) ?
+ rtrim(substr($value, 0, $pos)) : $value;
+ }
+ // if block is set, we strip line of slashes
+ $_ENV[$var] = $block === true ? stripslashes($value) : $value;
+ // set successful load
+ $status = 0;
+ }
+ } elseif ($block === true) {
+ // read line until there is a unescaped "
+ // this also strips everything after the last "
+ if (preg_match("/(.*[^\\\])\"/", $line, $matches)) {
+ $block = false;
+ // strip ending " and EVERYTHING that follows after that
+ $line = $matches[1];
+ }
+ // strip line of slashes
+ $_ENV[$var] .= stripslashes($line);
+ }
+ }
+ fclose($fp);
+ return $status;
+ }
+}
+
+// __END__
diff --git a/www/lib/CoreLibs/Get/ReadEnvFile.php b/www/lib/CoreLibs/Get/ReadEnvFile.php
index 69a5881e..81eecfe5 100644
--- a/www/lib/CoreLibs/Get/ReadEnvFile.php
+++ b/www/lib/CoreLibs/Get/ReadEnvFile.php
@@ -4,8 +4,14 @@ declare(strict_types=1);
namespace CoreLibs\Get;
+/**
+ * @deprecated use \CoreLibs\Get\DotEnv instead
+ */
class ReadEnvFile
{
+ /** @var string constant comment char, set to # */
+ private const COMMENT_CHAR = '#';
+
/**
* parses .env file
*
@@ -24,71 +30,16 @@ class ReadEnvFile
* @return int -1 other error
* 0 for success full load
* 1 for file loadable, but no data inside
- * 2 for file not readable
+ * 2 for file not readable or open failed
* 3 for file not found
+ * @deprecated Use \CoreLibs\Get\DotEnv::readEnvFile() instead
*/
public static function readEnvFile(
string $path = __DIR__,
string $env_file = '.env'
): int {
- // default -1;
- $status = -1;
- $env_file_target = $path . DIRECTORY_SEPARATOR . $env_file;
- // this is not a file -> abort
- if (!is_file($env_file_target)) {
- $status = 3;
- return $status;
- }
- // cannot open file -> abort
- if (($fp = fopen($env_file_target, 'r')) === false) {
- $status = 2;
- return $status;
- }
- // set to readable but not yet any data loaded
- $status = 1;
- $block = false;
- $var = '';
- while ($line = fgets($fp)) {
- // main match for variable = value part
- if (preg_match("/^\s*([\w_.]+)\s*=\s*((\"?).*)/", $line, $matches)) {
- $var = $matches[1];
- $value = $matches[2];
- $quotes = $matches[3];
- // write only if env is not set yet, and write only the first time
- if (empty($_ENV[$var])) {
- if (!empty($quotes)) {
- // match greedy for first to last so we move any " if there are
- if (preg_match('/^"(.*[^\\\])"/U', $value, $matches)) {
- $value = $matches[1];
- } else {
- // this is a multi line
- $block = true;
- // first " in string remove
- // add removed new line back because this is a multi line
- $value = ltrim($value, '"') . PHP_EOL;
- }
- }
- // if block is set, we strip line of slashes
- $_ENV[$var] = $block === true ? stripslashes($value) : $value;
- // set successful load
- $status = 0;
- }
- } elseif ($block === true) {
- // read line until there is a unescaped "
- // this also strips everything after the last "
- if (preg_match("/(.*[^\\\])\"/", $line, $matches)) {
- $block = false;
- // strip ending " and EVERYTHING that follows after that
- $line = $matches[1];
- }
- // strip line of slashes
- $_ENV[$var] .= stripslashes($line);
- }
- }
- fclose($fp);
- return $status;
+ return \CoreLibs\Get\DotEnv::readEnvFile($path, $env_file);
}
}
-
// __END__
diff --git a/www/vendor/composer/autoload_classmap.php b/www/vendor/composer/autoload_classmap.php
index 91a57e0c..c7f04f9e 100644
--- a/www/vendor/composer/autoload_classmap.php
+++ b/www/vendor/composer/autoload_classmap.php
@@ -40,6 +40,7 @@ return array(
'CoreLibs\\Debug\\MemoryUsage' => $baseDir . '/lib/CoreLibs/Debug/MemoryUsage.php',
'CoreLibs\\Debug\\RunningTime' => $baseDir . '/lib/CoreLibs/Debug/RunningTime.php',
'CoreLibs\\Debug\\Support' => $baseDir . '/lib/CoreLibs/Debug/Support.php',
+ 'CoreLibs\\Get\\DotEnv' => $baseDir . '/lib/CoreLibs/Get/DotEnv.php',
'CoreLibs\\Get\\ReadEnvFile' => $baseDir . '/lib/CoreLibs/Get/ReadEnvFile.php',
'CoreLibs\\Get\\System' => $baseDir . '/lib/CoreLibs/Get/System.php',
'CoreLibs\\Language\\Core\\CachedFileReader' => $baseDir . '/lib/CoreLibs/Language/Core/CachedFileReader.php',
diff --git a/www/vendor/composer/autoload_static.php b/www/vendor/composer/autoload_static.php
index 9ec986ca..d9cb4fc2 100644
--- a/www/vendor/composer/autoload_static.php
+++ b/www/vendor/composer/autoload_static.php
@@ -105,6 +105,7 @@ class ComposerStaticInit10fe8fe2ec4017b8644d2b64bcf398b9
'CoreLibs\\Debug\\MemoryUsage' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/MemoryUsage.php',
'CoreLibs\\Debug\\RunningTime' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/RunningTime.php',
'CoreLibs\\Debug\\Support' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Support.php',
+ 'CoreLibs\\Get\\DotEnv' => __DIR__ . '/../..' . '/lib/CoreLibs/Get/DotEnv.php',
'CoreLibs\\Get\\ReadEnvFile' => __DIR__ . '/../..' . '/lib/CoreLibs/Get/ReadEnvFile.php',
'CoreLibs\\Get\\System' => __DIR__ . '/../..' . '/lib/CoreLibs/Get/System.php',
'CoreLibs\\Language\\Core\\CachedFileReader' => __DIR__ . '/../..' . '/lib/CoreLibs/Language/Core/CachedFileReader.php',