Skip to content

Commit

Permalink
Merge pull request #10 from byjg/4.9
Browse files Browse the repository at this point in the history
Fix !bool
  • Loading branch information
byjg authored Jun 5, 2024
2 parents 262645b + e44b7c5 commit 6b5f7fe
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: byjg
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Contributing to byjg/php-config

First of all, thank you for taking the time to contribute!

## How to Contribute

### Issues

If you encounter any issues, have questions, or need clarification, please open an issue on our [Issues page](https://github.com/your-repo/issues). This helps us track and prioritize bug fixes and enhancements.

### Branches

We have three main branches in this project:

- **master**: Contains the latest code. It is generally stable, but we recommend using it with caution.
- **a.b**: Use this branch for creating PRs. The naming convention follows `a.b`, where `a` is the major release and `b` is the minor release of the current version. For example, if the current release is 4.9.2, use the branch `4.9` for your PR. You can also use `4.9.x-dev` in your composer for development purposes.
- **future release**: This branch is typically `(a+1).0`. For instance, if the current release is 4.9.2, the future release branch will be `5.0`.


### Code Style and Guidelines

- **Follow PSR Standards**: We follow [PSR-1](https://www.php-fig.org/psr/psr-1/), [PSR-2](https://www.php-fig.org/psr/psr-2/), and [PSR-12](https://www.php-fig.org/psr/psr-12/).
- **Write Clear Commit Messages**: Use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
- **Documentation**: Update the documentation for any new features or changes.

### Common Practices

- **Keep Pull Requests Small**: Smaller PRs are easier to review and merge. Focus on one feature or fix per PR.
- **Write Tests**: Ensure your changes are covered by tests. We aim for a high level of test coverage.
- **Respect Reviewers' Time**: Be responsive to feedback and willing to make necessary changes.

### Community

- **Be Respectful**.
- **Collaborate**: We encourage collaboration and open discussion. Don’t hesitate to ask for help or provide feedback.

Thank you for contributing to byjg/php-config! Your help is appreciated and makes a big difference.
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
},
"require-dev": {
"byjg/cache-engine": "4.9.*",
"phpunit/phpunit": "5.7.*|7.4.*|^9.5"
"phpunit/phpunit": "5.7.*|7.4.*|^9.5",
"ext-json": "*"
},
"prefer-stable": true,
"minimum-stability": "dev",
Expand All @@ -19,6 +20,9 @@
"ByJG\\Config\\": "src/"
}
},
"suggest": {
"ext-json": "*"
},
"autoload-dev": {
"psr-4": {
"Test\\": "tests/"
Expand Down
10 changes: 9 additions & 1 deletion config/config-file.env
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,12 @@ KEY8='!jsondecode {"key1":"value1","key2":"value2"}'

KEY9=!array 1,2,3,4,5

KEY10=!dict key1=value1,key2=value2
KEY10="!dict key1=value1,key2=value2"

KEY11 = !bool false

KEY12 ="!unesc Test\nTest\n"

KEY13 = "Test2\nTest2\n"

KEY14 = !file ../config/test.txt
2 changes: 2 additions & 0 deletions config/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file
content
2 changes: 2 additions & 0 deletions docs/special-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Where `!parser` is one of the pre-defined parsers:
| !jsondecode | Parse to JSON and transform to an array | `PARAM=!jsondecode {"a":"b"}` |
| !array | Parse to array | `PARAM=!array 1,2,3,4` |
| !dict | Parse to dictionary (associative array) | `PARAM=!dict a=1,b=2` |
| !unesc | Unescape the value | `PARAM=!unesc a\nb` |
| !file | Load the content of a file | `PARAM=!file /path/to/file` |


## Adding a new Parser
Expand Down
26 changes: 25 additions & 1 deletion src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ protected function processEagerSingleton()
}
}

public function releaseSingletons($exceptList = [])
{
foreach ($this->config as $key => $value) {
if ($value instanceof DependencyInjection and !in_array($key, $exceptList)) {
$value->releaseInstance();
}
}
}

protected function initializeParsers()
{
if (ParamParser::isParserExists('initialized')) {
Expand All @@ -187,7 +196,7 @@ protected function initializeParsers()
return true;
});
ParamParser::addParser('bool', function ($value) {
return boolval($value);
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
});
ParamParser::addParser('int', function ($value) {
return intval($value);
Expand Down Expand Up @@ -221,5 +230,20 @@ protected function initializeParsers()
ParamParser::addParser('unserialize', function ($value) {
return unserialize(base64_decode($value));
});

ParamParser::addParser('unesc', function ($value) {
return htmlspecialchars_decode(stripcslashes($value));
});

ParamParser::addParser('file', function ($value) {
if ($value[0] !== '/') {
$value = __DIR__ . '/' . $value;
}

if (!file_exists($value)) {
throw new ConfigException("File '$value' not found");
}
return file_get_contents($value);
});
}
}
13 changes: 10 additions & 3 deletions src/Definition.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class Definition

private $baseDir = "";

/**
* @var bool|array
*/
private $loadOsEnv = false;

private $configName = null;
Expand Down Expand Up @@ -129,9 +132,9 @@ public function addEnvironment(Environment $config)
/**
* @return $this
*/
public function withOSEnvironment()
public function withOSEnvironment($keys = [])
{
$this->loadOsEnv = true;
$this->loadOsEnv = is_array($keys) && empty($keys) ? true : $keys;
return $this;
}

Expand Down Expand Up @@ -246,8 +249,12 @@ public function build($configName = null)
}
}

if ($this->loadOsEnv) {
if ($this->loadOsEnv === true) {
$config = array_merge($config, $_ENV);
} elseif (is_array($this->loadOsEnv)) {
foreach ($this->loadOsEnv as $key) {
$config[$key] = $_ENV[$key] ?? "";
}
}

return new Container($config, $configName, $this->configList[$configName]->getCacheInterface() ?? null);
Expand Down
7 changes: 7 additions & 0 deletions src/DependencyInjection.php
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,11 @@ public function isEagerSingleton()
{
return $this->eager;
}

public function releaseInstance()
{
if (!empty($this->instance) && !$this->isEagerSingleton()) {
$this->instance = null;
}
}
}
53 changes: 53 additions & 0 deletions tests/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,57 @@ public function testNotAllowCreateDefinitionFromAbstract()
$defintion->build();
}

public function testLoadFromOSAllEnv()
{
$environment = new Environment('test');

putenv('APP_ENV=test');
$_ENV['APP_ENV'] = 'test';
$_ENV['X'] = 'abc';
$_ENV['Y'] = 'def';
$defintion = (new Definition())
->addEnvironment($environment)
->withOSEnvironment();

$container = $defintion->build();

$this->assertEquals('abc', $container->get('X'));
$this->assertEquals('def', $container->get('Y'));
}

public function testLoadFromOSPartialEnv()
{
$environment = new Environment('test');

putenv('APP_ENV=test');
$_ENV['APP_ENV'] = 'test';
$_ENV['X'] = 'abc';
$_ENV['Y'] = 'def';
$defintion = (new Definition())
->addEnvironment($environment)
->withOSEnvironment(['X']);

$container = $defintion->build();

$this->assertEquals('abc', $container->get('X'));
$this->assertFalse($container->has('Y'));
}

public function testLoadFromOSNoEnv()
{
$environment = new Environment('test');

putenv('APP_ENV=test');
$_ENV['APP_ENV'] = 'test';
$_ENV['X'] = 'abc';
$_ENV['Y'] = 'def';
$defintion = (new Definition())
->addEnvironment($environment);

$container = $defintion->build();

$this->assertFalse($container->has('X'));
$this->assertFalse($container->has('Y'));
}

}
35 changes: 34 additions & 1 deletion tests/DependencyInjectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,40 @@ public function testWithFactoryMethodSingleton()
$this->assertEquals(40, $random->getNumber());
}

public function testReleaseSingleton()
{
$config = $this->object->build('di-test3');

// Sanity check to verify if a non-singleton always return a new object
$instance1 = $config->get("factory");
$this->assertInstanceOf(Random::class, $instance1);

$instance2 = $config->get("factory");
$this->assertInstanceOf(Random::class, $instance2);

$this->assertNotSame($instance1, $instance2);

// Check if Singleton is returning the same object
$singleton1 = $config->get("factory2");
$this->assertInstanceOf(Random::class, $singleton1);

$singleton2 = $config->get("factory2");
$this->assertInstanceOf(Random::class, $singleton2);

$this->assertSame($singleton1, $singleton2);

// Release the singleton and check if a new is created
$config->releaseSingletons();

$this->assertEquals(40, $singleton1->getNumber()); // Make sure the local variable is running

$singleton3 = $config->get("factory2");
$this->assertInstanceOf(Random::class, $singleton3);

$this->assertNotSame($singleton1, $singleton3);
}


public function testGetInstancesWithParam()
{
$config = $this->object->build('di-test4');
Expand Down Expand Up @@ -236,5 +270,4 @@ public function testGetInstancesFail3_2()
$this->assertEquals(24, $injectedLegacy->calculate());
}


}
6 changes: 5 additions & 1 deletion tests/EnvFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public function testgetCurrentEnvironment()
$this->assertSame(["key1" => "value1", "key2" => "value2"], $config->get('KEY8'));
$this->assertSame(['1', '2', '3', '4', '5'], $config->get('KEY9'));
$this->assertSame(["key1" => "value1", "key2" => "value2"], $config->get('KEY10'));
$this->assertFalse($config->get('KEY11'));
$this->assertEquals("Test\nTest\n", $config->get('KEY12'));
$this->assertEquals("Test2\\nTest2\\n", $config->get('KEY13'));
$this->assertEquals("file\ncontent\n", $config->get('KEY14'));
}

public function testSaveToCacheBeforeChange()
Expand Down Expand Up @@ -82,4 +86,4 @@ public function testMissingCustomParser()
$config->get('KEY11');
}

}
}

0 comments on commit 6b5f7fe

Please sign in to comment.