Skip to content

Commit

Permalink
Version 2 development
Browse files Browse the repository at this point in the history
  • Loading branch information
ElGigi committed Mar 11, 2021
1 parent b0fadf1 commit 9e8b981
Show file tree
Hide file tree
Showing 55 changed files with 1,657 additions and 1,177 deletions.
6 changes: 1 addition & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
language: php
php:
- 7.1
- 7.2
- 7.3
- 7.4
- 8.0snapshot
- 8.0

before_install:
- sudo apt-get -qq update
Expand Down
37 changes: 34 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning] (http://semver.org/).
For change log format, use [Keep a Changelog] (http://keepachangelog.com/).

All notable changes to this project will be documented in this file. This project adheres
to [Semantic Versioning] (http://semver.org/). For change log format,
use [Keep a Changelog] (http://keepachangelog.com/).

## [2.0.0-alpha1]

### Added

- Adapter concept
- Config object to manage adapters
- Dependency with `colinodell/json5` library to parse JSON5 syntax
- New adapter IniAdapter (INI string and files)
- New adapter ArrayAdapter (PHP array)

### Changed

- Refactoring
- Bump compatibility to PHP 8 minimum
- Actions replaced by functions
- Encapsulation of functions
- Functions must be alone in value of configuration key

### Removed

- Remove usage of `@extends` spacial key in configuration
- Remove merging of configurations, replaced by multiple config objects prioritized

## [1.2.0] - 2020-11-05

### Added

- PHP 8 compatibility

## [1.1.1] - 2020-09-23

### Changed

- Fix variable replacement by null with empty string

## [1.1.0] - 2020-04-17

### Added

- New `const` action to get constant value

## [1.0.0] - 2020-02-17

First version
235 changes: 111 additions & 124 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Berlioz Configuration

[![Latest Version](https://img.shields.io/packagist/v/berlioz/config.svg?style=flat-square)](https://github.com/BerliozFramework/Config/releases)
[![Software license](https://img.shields.io/github/license/BerliozFramework/Config.svg?style=flat-square)](https://github.com/BerliozFramework/Config/blob/master/LICENSE)
[![Build Status](https://img.shields.io/travis/com/BerliozFramework/Config/master.svg?style=flat-square)](https://travis-ci.com/BerliozFramework/Config)
[![Quality Grade](https://img.shields.io/codacy/grade/f290647a1f5143ec8299ecea9b83d6b1/master.svg?style=flat-square)](https://www.codacy.com/manual/BerliozFramework/Config)
[![Software license](https://img.shields.io/github/license/BerliozFramework/Config.svg?style=flat-square)](https://github.com/BerliozFramework/Config/blob/2.x/LICENSE)
[![Build Status](https://img.shields.io/travis/com/BerliozFramework/Config/2.x.svg?style=flat-square)](https://travis-ci.com/BerliozFramework/Config)
[![Quality Grade](https://img.shields.io/codacy/grade/f290647a1f5143ec8299ecea9b83d6b1/2.x.svg?style=flat-square)](https://www.codacy.com/manual/BerliozFramework/Config)
[![Total Downloads](https://img.shields.io/packagist/dt/berlioz/config.svg?style=flat-square)](https://packagist.org/packages/berlioz/config)

**Berlioz Configuration** is a PHP library to manage your configuration files.
Expand All @@ -20,167 +20,154 @@ $ composer require berlioz/config

### Dependencies

* **PHP** ^7.1 || ^8.0
* PHP libraries:
* **ext-json**
* **PHP** ^8.0
* Packages:
* **berlioz/helpers**

* **berlioz/helpers**
* **colinodell/json5**

## Usage

### Create configuration object

You can create configuration like this:
You can create the configuration with adapters. 3 default adapters are available:

- `ArrayAdapter`: accept a PHP array
- `IniAdapter`: accept a INI string or file
- `JsonAdapter`: accept a JSON/JSON5 string or file

Example:

```php
// Using files
$config = new JsonConfig('/path/of-project/config/config.json', true);
$config = new ExtendedJsonConfig('/path/of-project/config/config.json', true);
use Berlioz\Config\Adapter;
use Berlioz\Config\Config;

// Using data
$config = new JsonConfig('{"config": "test"}');
$config = new ExtendedJsonConfig('{"config": "test"}');
$arrayAdapter = new Adapter\ArrayAdapter([/*...*/]);
$iniAdapter = new Adapter\IniAdapter('/path/of-project/config/config.ini', true);
$jsonAdapter = new Adapter\JsonAdapter('/path/of-project/config/config.json', true);

$config = new Config([$arrayAdapter, $jsonAdapter, $iniAdapter]);
print $config->get('foo.bar.qux'); // Print value of configuration
```

Second parameter of constructor is if the first parameter is an URL.
Second parameter of `IniAdapter` and `JsonAdapter` constructors define that the first parameter is an url.

### Get value of key
The order of adapter is important, the first have priority... So the value returned by `get` method is the first adapter
to respond at key. If the value is an array, it will be merged with all adapters.

Configuration file:
```json
{
"var1": "value1",
"var2": {
"var3": "value3"
}
}
```
For more flexibility, you can define the priority by an integer in the constructor of adapters, withe the
parameter `priority`.

### Get value

To get value, you must call `get` method:

To get value, you must do like this:
```php
$config->get('var1'); // returns string 'value1'
$config->get('var2'); // returns array ['var3' => 'value3']
$config->get('var2.var3'); // returns 'value3'
$config->get('var3'); // returns NULL
$config->get('var3', true); // returns TRUE (default value given)
$config = new \Berlioz\Config\Config(/* ... */);

$config->get('foo'); // Returns value of key 'foo'
$config->get('foo.bar'); // Returns value of nested key 'foo.bar'
$config->get('baz', true); // Returns value of key 'baz' or TRUE default value if key does not exist
```

If you get an unknown value, the method return the default value given in second parameter else **NULL**.
The second parameter of `ConfigInterface::get()` method is the default value if key does not exist. Default value of
this parameter is `NULL`.

You can also test if a key exist:

You can also test if a key exists, like this:
```php
$config->has('var1'); // returns true
$config->has('var2'); // returns true
$config->has('var4'); // returns false
```
$config = new \Berlioz\Config\Config(/* ... */);

### Variables
$exists = $config->has('foo'); // Returns boolean
```

In values of JSON keys, you can add this syntax to use variables:
`%var1.var2%`,
that's get key **var1.var2** in replacement of value.
### Functions

Some variables are available by default:
`Config` object accept a set of functions. The syntax to call a function is: `{functionName:value}`.

- **php_version**: the value of constant PHP_VERSION
- **php_version_id**: the value of constant PHP_VERSION_ID
- **php_major_version**: the value of constant PHP_MAJOR_VERSION
- **php_minor_version**: the value of constant PHP_MINOR_VERSION
- **php_release_version**: the value of constant PHP_RELEASE_VERSION
- **php_sapi**: the value of constant PHP_SAPI
- **system_os**: the value of constant PHP_OS
- **system_os_family**: the value of constant PHP_OS_FAMILY
A function call must be alone in value of configuration key.

You can also define your own variables with the methods:
- `setVariable(string $name, mixed $value)`
- `setVariables(array $variables)`
Defaults functions:

**WARNING**: Priority is given to the user defined variable in the config object instead of JSON path.
- `config`: replace value by another part of config
- `constant`: replace value by a constant
- `env`: replace value by environment variable
- `var`: replace value by variable value

## Extended JSON format
Examples:

We created an extended format of the JSON format.
Just to do actions like include or extends JSON files.
```php
use Berlioz\Config\Adapter;
use Berlioz\Config\Config;

define('FOO', 'foo constant value');

$arrayAdapter = new Adapter\ArrayAdapter([
'foo' => '{constant:FOO}',
'bar' => [
'foo' => 'value2',
],
'baz' => '{config: bar.foo}',
'qux' => '{var: BAR}'
]);
$config = new Config([$arrayAdapter], ['BAR' => 'bar value']);

print $config->get('foo'); // Print "foo constant value"
print $config->get('baz'); // Print "value2"
print $config->get('qux'); // Print "bar value"
print_r($config->get('bar')); // Print array "['foo' => 'value2']"
```

### Syntax
### Variables

* Include another file: `%include:filename.json%`
* Extends a file: `%extends:filename.json, filename2.json, filename3.json%`
* Replace by an env variable: `%env:VAR_NAME%`
* Replace by a constant: `%const:VAR_NAME%` or `%constant:VAR_NAME%`
* Allow inline comments : `// My comment` (comment must be alone on a line)
You can define variables usable in configuration with function `var`.

You can define your own actions with static method `ExtendedJsonConfig::addAction(string $name, callable $callback)`.
Define variables in the constructor:

### Extends configurations files
```php
// Define variable in an array
$variables = [
'foo' => 'foo value',
'bar' => 'bar value',
];

You can extends the current configuration file with another with special key `@extends`:
```json
{
// Extends
"@extends": "another.json",
// Keys
"key": "value"
}
$config = new \Berlioz\Config\Config(variables: $variables);
```

### Example
You can also manipulate the variables after instantiation of config. Variables are stored in a `ArrayObject` object,
accessible with `Config::getVariables()` method:

File **config.json**:
```php
$config = new \Berlioz\Config\Config();

```json
{
"@extends": "config.another.json",
"var1": "value1",
"var2": {
"var3": "value3"
},
"var4": "%include:config3.json%",
"var5": "%extends:config3.json, config2.json%"
}
// Set variables
$config->getVariables()['foo'] = 'foo value';
$config->getVariables()['bar'] = 'bar value';

// Unset a variable
unset($config->getVariables()['bar']);
```

File **config.another.json**:
## Extend library

```json
{
"var.another": "value",
"var1": "valueX"
}
```
### Create an adapter

File **config2.json**:
You can create your own adapter. Only implements `\Berlioz\Config\Adapter\AdapterInterface` interface.

```json
{
"var6": "value1",
"var7": false
}
```
This interface has only 3 methods:

File **config3.json**:
- `AdapterInterface::getPriority(): int`
- `ConfigInterface::get(string $key, mixed $default = null): mixed`
- `ConfigInterface::has(string $key): bool`

```json
{
"var7": true
}
```
Look at the existent adapters in the source code of the library for inspiration.

The final config file is:

```json
{
"var.another": "value",
"var1": "value1",
"var2": {
"var3": "value3"
},
"var4": {
"var7": true
},
"var5": {
"var6": "value1",
"var7": false
}
}
```
### Create a function

You can create your owns functions. Only implements `\Berlioz\Config\ConfigFunction\ConfigFunctionInterface` interface.

This interface has only 2 methods:

- `ConfigFunctionInterface::getName(): string`
- `ConfigFunctionInterface::execute(string $str): mixed`

Look at the existent functions in the source code of the library for inspiration.
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
}
},
"require": {
"php": "^7.1 || ^8.0",
"ext-json": "*",
"berlioz/helpers": "^1.0"
"php": "^8.0",
"berlioz/helpers": "^1.0",
"colinodell/json5": "^2.2"
},
"require-dev": {
"phpunit/phpunit": "^7.5 || ^8.0 || ^9.0"
"phpunit/phpunit": "^9.3"
}
}
17 changes: 10 additions & 7 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php" colors="true">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="./tests/bootstrap.php"
colors="true"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Berlioz Framework Config test suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
</phpunit>
Loading

0 comments on commit 9e8b981

Please sign in to comment.