Skip to content

Commit

Permalink
Correct persist env
Browse files Browse the repository at this point in the history
  • Loading branch information
prinx committed Jun 12, 2020
1 parent 92abaf4 commit f9e5376
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 27 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EXAMPLE=true
145 changes: 120 additions & 25 deletions src/Dotenv.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,35 @@

namespace Prinx\Dotenv;

/**
* Main class representing the environment variables
*/
class Dotenv
{
protected $env = [];
protected $path = '';
protected $section_separator = '.';

public function __construct($path = '')
public function __construct(string $path = '')
{
$path = $path ?: realpath(__DIR__ . '/../../../../.env');
$this->setPath($path);

try {
$this->env = \parse_ini_file($this->path, true, INI_SCANNER_TYPED);
$this->env = array_merge($_ENV, $this->env);
} catch (\Throwable $th) {
throw new \Exception('An error happened when parsing the .env file: ' . $th->getMessage());
}

$this->replaceReferences();
}

/**
* Replace the references in the .env by their respective value
*
* @return void
*/
public function replaceReferences()
{
$env = file($this->path, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
Expand All @@ -53,7 +62,14 @@ public function replaceReferences()
}
}

public function properValueOfRef($ref_value, $line_value)
/**
* Assign the proper type of the reference to the replaced value
*
* @param mixed $ref_value
* @param mixed $line_value
* @return void
*/
public function properValueOfRef(mixed $ref_value, mixed $line_value)
{
if ($this->valueSameAsReference($ref_value, $line_value)) {
settype($line_value, gettype($ref_value));
Expand All @@ -62,7 +78,14 @@ public function properValueOfRef($ref_value, $line_value)
return $line_value;
}

public function valueSameAsReference($ref_value, $line_value)
/**
* Check the value is the same as it reference (It is not inside a sentence for exemple)
*
* @param mixed $ref_value
* @param mixed $line_value
* @return void
*/
public function valueSameAsReference(mixed $ref_value, mixed $line_value)
{
$ref_value_string = '';
$ref_value_type = gettype($ref_value);
Expand All @@ -74,8 +97,14 @@ public function valueSameAsReference($ref_value, $line_value)
return $ref_value_string === $line_value;
}

/**
* Check if var can be converted to string
*
* @param mixed $var
* @return bool
*/
// Thanks to https://stackoverflow.com/a/5496674
public function isStringifiable($var)
public function isStringifiable(mixed $var)
{
return (
!is_array($var) &&
Expand All @@ -84,12 +113,24 @@ public function isStringifiable($var)
);
}

/**
* Returns all the environment variables
*
* @return void
*/
public function all()
{
return $this->env;
}

public function get($name = null, $default = null)
/**
* Get a specific environment variableq
*
* @param string $name
* @param mixed $default
* @return void
*/
public function get(string $name = '', mixed $default = null)
{
if (\func_num_args() === 0) {
return $this->all();
Expand Down Expand Up @@ -126,9 +167,13 @@ public function get($name = null, $default = null)
}

/**
* Section not yet support
* Add an environment variables to the currently loaded environment variables
*
* @param string $name
* @param mixed $value
* @return void
*/
public function add($name, $value)
public function add(string $name, mixed $value)
{
$name_exploded = explode($this->section_separator, $name);

Expand All @@ -146,11 +191,20 @@ public function add($name, $value)
);
}

/**
* Returns the array corresponding to the current_index in name_indexes or returns the value_to_insert
*
* @param mixed $value_to_insert
* @param array $name_indexes
* @param int $current_index
* @param int $last_index
* @return mixed
*/
public function nextArrayValue(
$value_to_insert,
$name_indexes,
$current_index,
$last_index
mixed $value_to_insert,
array $name_indexes,
int $current_index,
int $last_index
) {
return $current_index === $last_index ?
$value_to_insert :
Expand All @@ -168,47 +222,88 @@ public function nextArrayValue(
* Write a new environment variable to the .env file
*
* @param string $name
* @param string $value
* @param boolean $overwrite If true, overwrite the variable if it was already in the file
* @param mixed $value
* @param bool $overwrite
* @param bool $overwrite If true, overwrites the variable if it was already in the file
* @return void
*/
public function persist($name, $value, $overwrite = true)
{
public function persist(
string $name,
mixed $value,
bool $overwrite = true,
bool $quote_string = true
) {
$pattern = '/' . $name . '[ ]*=.*/';
$content = \file_get_contents($this->path);
$env_variable_exists = $this->envVariableExists($name) || preg_match($pattern, $content);

$value = \is_string($value) && $quote_string ? '"' . $value . '"' : $value;
$line = $name . "=" . $value;
$env_variable_exists = $this->envVariableExists($line);

if ($env_variable_exists) {
return $overwrite ? preg_replace($this->line_pattern, $line) : null;
if ($env_variable_exists && $overwrite) {
$content = preg_replace($pattern, $line, $content);
file_put_contents($this->path, $content);
$this->add($name, $value);
} elseif (!$env_variable_exists) {
$line = $content ? "\n\n" . $line : $line;
file_put_contents($this->path, $line, FILE_APPEND);
$this->add($name, $value);
}

return file_put_contents($this->path, "\n\n" . $line, FILE_APPEND);
}

/**
* Determines if an environment variables exists
*
* @param string $name
* @return bool
*/
public function envVariableExists($name)
{
return isset($this->env[$name]);
return isset($this->env[$name]) || !!getenv($name);
}

// Thanks to https://stackoverflow.com/questions/9721952/search-string-and-return-line-php
public function getLineWithString($fileName, $str)
/**
* Get the line number of a string, in a file
*
* Thanks to https://stackoverflow.com/questions/9721952/search-string-and-return-line-php
* @param string $fileName
* @param string $str
* @return int
*/
public function getLineWithString(string $fileName, string $str)
{
$lines = file($fileName);
foreach ($lines as $lineNumber => $line) {
if (strpos($line, $str) !== false) {
return $line;
}
}

return -1;
}

public function addIfNotExists($name, $value, $section = '')
/**
* Add a value to the current loaded environment variables if the value is not already there
*
* @param string $name
* @param mixed $value
* @param string $section
* @return void
*/
public function addIfNotExists(string $name, mixed $value, string $section = '')
{
if (!isset($this->env[$name])) {
$this->add($name, $value, $section);
}
}

public function setPath($path)
/**
* Set the .env file path
*
* @param string $path
* @return void
*/
public function setPath(string $path)
{
if (!\file_exists($path)) {
throw new \Exception('Trying to set the env file path but the file ' . $path . ' seems not to exist.');
Expand Down
16 changes: 16 additions & 0 deletions src/DotenvInstance.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,20 @@

use Prinx\Dotenv\Dotenv;

/**
* Singleton class keeping the Dotenv instance
*/
class DotenvInstance
{
protected static $env_instance = null;

/**
* Returns the Dotenv instance
*
* It instanciate the Dotenv class if not yet instanciated.
*
* @return void
*/
public static function get()
{
if (!self::$env_instance) {
Expand All @@ -25,6 +35,12 @@ public static function get()
return self::$env_instance;
}

/**
* Initialise the Dotenv instance
*
* @param string $path Path to the .env file
* @return void
*/
public static function load($path = null)
{
self::$env_instance = new Dotenv($path);
Expand Down
46 changes: 44 additions & 2 deletions src/env.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@

use Prinx\Dotenv\DotenvInstance;

/**
* Retrieve an environment variable.
*
* Look for an environment variables in the current .env file,
* the $_ENV superglobal and using the built-in getenv function
*
* @param string $name
* @param mixed $default
* @return void
*/
function env($name = null, $default = null)
{
$env = DotenvInstance::get();
Expand All @@ -27,32 +37,64 @@ function env($name = null, $default = null)
}
}

/**
* Add a temporary environment variable to the current loaded environment variables
*
* @param string $name
* @param mixed $value
* @return void
*/
function addEnv($name, $value)
{
$env = DotenvInstance::get();

\call_user_func([$env, 'add'], $name, $value);
}

function persistEnv($name, $value)
/**
* Write an environment variable to the loaded .env file
*
* @param string $name
* @param mixed $value
* @param bool $overwrite
* @param bool $quote_string
* @return void
*/
function persistEnv($name, $value, $overwrite = true, $quote_string = true)
{
$env = DotenvInstance::get();

\call_user_func([$env, 'persist'], $name, $value);
\call_user_func([$env, 'persist'], $name, $value, $overwrite, $quote_string);
}

/**
* Returns all the environment variables in the .env file as an array
*
* @return void
*/
function allEnv()
{
$env = DotenvInstance::get();

\call_user_func([$env, 'all']);
}

/**
* Returns the Dotenv instance
*
* @return void
*/
function dotenv()
{
return DotenvInstance::get();
}

/**
* Load a specific .env file
*
* @param string $path
* @return void
*/
function loadEnv($path = null)
{
DotenvInstance::load($path);
Expand Down

0 comments on commit f9e5376

Please sign in to comment.