Skip to content

Commit

Permalink
Merge pull request #3 from jaumarar/process-quotes
Browse files Browse the repository at this point in the history
Added process of quotes
  • Loading branch information
F. Michel authored Jul 4, 2021
2 parents e6d703b + 1c906db commit e61e0a0
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 42 deletions.
50 changes: 43 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,58 @@
```
APP_ENV=dev
DATABASE_DNS=mysql:host=localhost;dbname=test;
DATABASE_USER=root
DATABASE_USER="root"
DATABASE_PASSWORD=root
MODULE_ENABLED=true
```

**How to use ?**
## Load the variables

```php
<?php
use DevCoder\DotEnv;

(new DotEnv(__DIR__ . '/.env'))->load();
$absolutePathToEnvFile = __DIR__ . '/.env';

echo getenv('APP_ENV');
// dev
echo getenv('DATABASE_DNS');
// mysql:host=localhost;dbname=test;
(new DotEnv($absolutePathToEnvFile))->load();
```

# Use them!
```php
/**
* string(33) "mysql:host=localhost;dbname=test;"
*/
var_dump(getenv('DATABASE_DNS'));

/**
* Removes double and single quotes from the variable:
*
* string(4) "root"
*/
var_dump(getenv('DATABASE_USER'));

/**
* Processes booleans as such:
*
* bool(true)
*/
var_dump(getenv('MODULE_ENABLED'));
```

Ideal for small project

Simple and easy!

# Processors

Also the variables are parsed according to the configuration passed as parameter to the constructor. The available processors are:

## BooleanProcessor

``VARIABLE=false`` will be processed to ```bool(false)```

NOTE: ``VARIABLE="true"`` will be processed to ```string(4) "true"```

## QuotedProcessor

``VARIABLE="anything"`` will be processed to ```string(8) "anything"```
75 changes: 47 additions & 28 deletions src/DotEnv.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,12 @@

namespace DevCoder;

use DevCoder\Processor\AbstractProcessor;
use DevCoder\Processor\BooleanProcessor;
use DevCoder\Processor\QuotedProcessor;

class DotEnv
{
/**
* Convert true and false to booleans, instead of:
*
* VARIABLE=false -> ['VARIABLE' => 'false']
*
* it will be
*
* VARIABLE=false -> ['VARIABLE' => false]
*
* default = true
*/
const PROCESS_BOOLEANS = 'PROCESS_BOOLEANS';

/**
* The directory where the .env file can be located.
*
Expand All @@ -27,26 +18,42 @@ class DotEnv
/**
* Configure the options on which the parsed will act
*
* @var array
* @var string[]
*/
protected $options = [];
protected $processors = [];

public function __construct(string $path, array $options = [])
public function __construct(string $path, array $processors = null)
{
if (!file_exists($path)) {
throw new \InvalidArgumentException(sprintf('%s does not exist', $path));
}

$this->path = $path;

$this->processOptions($options);
$this->setProcessors($processors);
}

private function processOptions(array $options) : void
private function setProcessors(array $processors = null) : DotEnv
{
$this->options = array_merge([
static::PROCESS_BOOLEANS => true
], $options);
/**
* Fill with default processors
*/
if ($processors === null) {
$this->processors = [
BooleanProcessor::class,
QuotedProcessor::class
];

return $this;
}

foreach ($processors as $processor) {
if (is_subclass_of($processor, AbstractProcessor::class)) {
$this->processors[] = $processor;
}
}

return $this;
}

/**
Expand Down Expand Up @@ -78,19 +85,31 @@ public function load() : void
}
}

private function processValue(string $value) {
/**
* Process the value with the configured processors
*
* @param string $value The value to process
* @return string|bool
*/
private function processValue(string $value)
{
/**
* First trim spaces and quotes if configured
*/
$trimmedValue = trim($value);

if (!empty($this->options[static::PROCESS_BOOLEANS])) {
$loweredValue = strtolower($trimmedValue);

$isBoolean = in_array($loweredValue, ['true', 'false'], true);
foreach ($this->processors as $processor) {
/** @var AbstractProcessor $processorInstance */
$processorInstance = new $processor($trimmedValue);

if ($isBoolean) {
return $loweredValue === 'true';
if ($processorInstance->canBeProcessed()) {
return $processorInstance->execute();
}
}

/**
* Does not match any processor options, return as is
*/
return $trimmedValue;
}
}
16 changes: 16 additions & 0 deletions src/Processor/AbstractProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
namespace DevCoder\Processor;

abstract class AbstractProcessor implements IProcessor
{
/**
* The value to process
* @var string
*/
protected $value;

public function __construct(string $value)
{
$this->value = $value;
}
}
17 changes: 17 additions & 0 deletions src/Processor/BooleanProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
namespace DevCoder\Processor;

class BooleanProcessor extends AbstractProcessor
{
public function canBeProcessed(): bool
{
$loweredValue = strtolower($this->value);

return in_array($loweredValue, ['true', 'false'], true);
}

public function execute()
{
return strtolower($this->value) === 'true';
}
}
11 changes: 11 additions & 0 deletions src/Processor/IProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
namespace DevCoder\Processor;

interface IProcessor
{
public function __construct(string $value);

public function canBeProcessed(): bool;

public function execute();
}
31 changes: 31 additions & 0 deletions src/Processor/QuotedProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace DevCoder\Processor;

class QuotedProcessor extends AbstractProcessor
{
public function canBeProcessed(): bool
{
$wrappedByDoubleQuotes = $this->isWrappedByChar($this->value, '"');

if ($wrappedByDoubleQuotes) {
return true;
}

return $this->isWrappedByChar($this->value, '\'');
}

public function execute()
{
/**
* Since this function is used for the quote removal
* we don't need mb_substr
*/
return substr($this->value, 1, -1);
}

private function isWrappedByChar(string $value, string $char) : bool
{
return $value[0] === $char && $value[-1] === $char;
}
}
Loading

0 comments on commit e61e0a0

Please sign in to comment.