-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of the INI Configuration Driver for CommonPHP. This commit introduces the core functionality for loading and saving INI file configurations, integrating seamlessly with the CommonPHP Configuration Management system. Features include robust error handling, support for nested structures, and compatibility with the CommonPHP Driver Management framework.
- Loading branch information
0 parents
commit 94fdcc3
Showing
11 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: PHP CI/CD Pipeline | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Setup PHP | ||
uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: '8.3' | ||
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite | ||
coverage: xdebug | ||
|
||
- name: Validate composer.json and composer.lock | ||
run: composer validate | ||
|
||
- name: Install dependencies | ||
run: composer install --prefer-dist --no-progress | ||
|
||
- name: Run tests | ||
run: ./vendor/bin/phpunit tests | ||
|
||
# If you have a deployment step, you can include it here. | ||
# This could be pushing to a Docker registry, deploying to a cloud platform, etc. | ||
# - name: Deploy... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.dev/ | ||
.idea/ | ||
composer.lock | ||
vendor/ | ||
.phpunit.result.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<component name="ProjectRunConfigurationManager"> | ||
<configuration default="false" name="phpmd" type="PhpLocalRunConfigurationType" factoryName="PHP Console" path="$PROJECT_DIR$/vendor/bin/phpmd" scriptParameters="../../src ansi cleancode,codesize,controversial,design,naming,unusedcode"> | ||
<method v="2" /> | ||
</configuration> | ||
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<component name="ProjectRunConfigurationManager"> | ||
<configuration default="false" name="phpstan" type="PhpLocalRunConfigurationType" factoryName="PHP Console" path="$PROJECT_DIR$/vendor/bin/phpstan" scriptParameters="analyse -c ..\..\phpstan.neon"> | ||
<method v="2" /> | ||
</configuration> | ||
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 commonphp | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# INI Configuration Driver for CommonPHP | ||
|
||
This library introduces the INI configuration driver, `IniConfigurationDriver`, as part of the CommonPHP Configuration Management ecosystem. It extends the functionality of CommonPHP by allowing applications to seamlessly load and save configurations using INI files. | ||
|
||
## Features | ||
|
||
- **Load INI Configurations**: Simplifies the process of reading INI files and converting them into associative arrays for easy access within PHP applications. | ||
- **Save Configurations as INI**: Offers the ability to serialize PHP associative arrays back into INI format, preserving the structure and hierarchies. | ||
- **Structured Error Handling**: Incorporates detailed exception handling to manage potential parsing and file operation errors effectively. | ||
- **Support for Nested Structures**: Through a custom implementation, it supports the representation of nested structures within INI files, providing greater flexibility in configuration management. | ||
|
||
## Installation | ||
|
||
Use Composer to integrate both the Configuration Manager and the INI driver into your project: | ||
|
||
``` | ||
composer require comphp/config | ||
composer require comphp/config-ini | ||
``` | ||
|
||
## Usage | ||
|
||
To utilize the INI driver with the Configuration Manager, first ensure the `DriverManager` is configured to recognize the INI driver: | ||
|
||
```php | ||
use CommonPHP\Drivers\DriverManager; | ||
use CommonPHP\Configuration\Drivers\IniConfigurationDriver\IniConfigurationDriver; | ||
|
||
$driverManager = new DriverManager(); | ||
$driverManager->enable(IniConfigurationDriver::class); | ||
``` | ||
|
||
Upon configuration, the `IniConfigurationDriver` will be automatically used for `.ini` file extensions, thanks to the `#[ConfigurationDriverAttribute('ini')]` annotation. | ||
|
||
### Loading a Configuration File | ||
|
||
```php | ||
$configManager->loadDriver(IniConfigurationDriver::class); | ||
$config = $configManager->get('path/to/configuration.ini'); | ||
``` | ||
|
||
### Saving a Configuration File | ||
|
||
After loading the driver as described above, modifications can be saved back to the INI file: | ||
|
||
```php | ||
$config->data['newSection'] = ['newKey' => 'newValue']; | ||
$config->save(); // Persists the changes to 'path/to/configuration.ini' | ||
``` | ||
|
||
## Exception Handling | ||
|
||
The driver includes specific exception handling for common issues such as: | ||
|
||
- **ConfigurationException**: Thrown for errors related to INI file parsing or when the file format does not meet the expected structure. | ||
- **General Exceptions**: For file read/write operations or parsing failures. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "comphp/config-ini", | ||
"type": "library", | ||
"description": "Provides functionality necessary for working with INI configuration files", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "timothy.mcclatchey", | ||
"email": "timothy@commonphp.org" | ||
} | ||
], | ||
"autoload": { | ||
"psr-4": { | ||
"CommonPHP\\Configuration\\Drivers\\IniConfigurationDriver\\": "src/" | ||
} | ||
}, | ||
"autoload-dev": { | ||
"psr-4": { | ||
"CommonPHP\\Tests\\Drivers\\IniConfigurationDriver\\": "tests/" | ||
} | ||
}, | ||
"require": { | ||
"php": "^8.3", | ||
"comphp/config": "^0.1" | ||
}, | ||
"require-dev": { | ||
"phpunit/phpunit": "^10.5.9", | ||
"phpstan/phpstan": "^1.10.58", | ||
"phpmd/phpmd": "^2.13" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
parameters: | ||
level: 9 | ||
paths: | ||
- src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
<?php /** @noinspection PhpUnused */ | ||
namespace CommonPHP\Configuration\Drivers\IniConfigurationDriver; | ||
|
||
use CommonPHP\Configuration\Attributes\ConfigurationDriverAttribute; | ||
use CommonPHP\Configuration\Contracts\ConfigurationDriverContract; | ||
use CommonPHP\Configuration\Exceptions\ConfigurationException; | ||
use Override; | ||
|
||
/** | ||
* Class IniConfigurationDriver | ||
* | ||
* This class implements the ConfigurationDriverContract interface and provides methods to load and save configuration data | ||
* from/to INI files. | ||
* | ||
* @package CommonPHP\Configuration\Drivers\IniConfigurationDriver | ||
*/ | ||
#[ConfigurationDriverAttribute('ini')] | ||
class IniConfigurationDriver implements ConfigurationDriverContract | ||
{ | ||
|
||
/** | ||
* Checks whether the object can be saved. | ||
* | ||
* @return bool Returns true if the object can be saved, false otherwise. | ||
*/ | ||
#[Override] function canSave(): bool | ||
{ | ||
return true; | ||
} | ||
|
||
/** | ||
* Loads an INI file and returns its contents as an associative array. | ||
* | ||
* @param string $filename The path to the INI file to load. | ||
* @return array The contents of the INI file as an associative array. | ||
* @throws ConfigurationException If the file does not appear to be a properly formatted INI file. | ||
*/ | ||
#[Override] function load(string $filename): array | ||
{ | ||
$result = parse_ini_file($filename); | ||
if ($result === false) | ||
{ | ||
throw new ConfigurationException('File does not appear to be a properly formatted INI file: '.$filename); | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* Saves an array of data to an INI file. | ||
* | ||
* @param string $filename The path to the INI file to be saved. | ||
* @param array $data The data to be saved to the INI file. | ||
* | ||
* @return void | ||
* @throws ConfigurationException | ||
*/ | ||
#[Override] function save(string $filename, array $data): void | ||
{ | ||
$result = $this->generateIniLines($data); | ||
$this->writeToFile($filename, $result); | ||
} | ||
|
||
/** | ||
* Generate INI lines based on the provided data. | ||
* | ||
* @param array $data The data to generate INI lines from. | ||
* @return array The generated INI lines. | ||
*/ | ||
private function generateIniLines(array $data): array | ||
{ | ||
$result = []; | ||
foreach ($data as $key => $val) { | ||
if (is_array($val)) { | ||
$result[] = "[$key]"; | ||
$result = array_merge($result, $this->generateSubLines($val)); | ||
continue; | ||
} | ||
$result[] = $this->generateLine($key, $val); | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* Generates an array of sublines based on the given subData array. | ||
* | ||
* @param array $subData The array containing subData. | ||
* @return array The array of generated sublines. | ||
*/ | ||
private function generateSubLines(array $subData): array | ||
{ | ||
$result = []; | ||
foreach ($subData as $sKey => $sVal) { | ||
$result[] = $this->generateLine($sKey, $sVal); | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* Generates a formatted line for a key-value pair. | ||
* | ||
* @param string $key The key of the pair. | ||
* @param string|int $value The value of the pair. | ||
* @return string The formatted line. | ||
*/ | ||
private function generateLine(string $key, string|int $value): string | ||
{ | ||
return "$key = " . (is_numeric($value) ? $value : '"' . $value . '"'); | ||
} | ||
|
||
/** | ||
* Writes an array of lines to a file. | ||
* | ||
* @param string $filename The path to the file to write to. | ||
* @param array $lines The lines to be written to the file. | ||
* @throws ConfigurationException if an unexpected error occurs while trying to save the file. | ||
*/ | ||
private function writeToFile(string $filename, array $lines): void | ||
{ | ||
$success = file_put_contents($filename, implode("\r\n", $lines)); | ||
if ($success === false) { | ||
throw new ConfigurationException('An unexpected error occurred while trying to save INI file: ' . $filename); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
namespace CommonPHP\Tests\Drivers\IniConfigurationDriver; | ||
|
||
use CommonPHP\Configuration\Drivers\IniConfigurationDriver\IniConfigurationDriver; | ||
use CommonPHP\Configuration\Exceptions\ConfigurationException; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
/** | ||
* Class IniConfigurationDriverTest | ||
* | ||
* Tests for the IniConfigurationDriver class. | ||
*/ | ||
class IniConfigurationDriverTest extends TestCase | ||
{ | ||
/** | ||
* @var IniConfigurationDriver | ||
*/ | ||
protected IniConfigurationDriver $driver; | ||
|
||
/** | ||
* Setting up for test case | ||
*/ | ||
protected function setUp(): void | ||
{ | ||
$this->driver = new IniConfigurationDriver(); | ||
} | ||
|
||
/** | ||
* Test for the `load` method | ||
* @throws ConfigurationException | ||
*/ | ||
public function testLoad() | ||
{ | ||
// Test case: when the file exists and is valid INI format | ||
$filename = rtrim(__DIR__, '\\/').DIRECTORY_SEPARATOR.'test.ini'; | ||
$data = $this->driver->load($filename); | ||
|
||
|
||
$this->assertEquals(['answerToLifeUniverseEverything' => 42], $data); | ||
|
||
// Test case: when the file does not exist or is invalid INI format | ||
$this->expectException(ConfigurationException::class); | ||
$filename = 'path/to/invalid/test.ini'; | ||
$this->driver->load($filename); | ||
} | ||
|
||
/** | ||
* Test to verify that save method writes correctly to an ini file. | ||
*/ | ||
public function testSuccessfulSave(): void | ||
{ | ||
$filename = rtrim(__DIR__, '\\/').DIRECTORY_SEPARATOR.'test.ini'; | ||
$data = ['answerToLifeUniverseEverything' => 42]; | ||
$this->driver->save($filename, $data); | ||
|
||
$this->assertFileExists($filename); | ||
$this->assertIsArray(parse_ini_file($filename, true)); | ||
} | ||
|
||
/** | ||
* Test to verify that save method throws exception when write operation fails. | ||
*/ | ||
public function testSavingToFileFailure(): void | ||
{ | ||
$this->expectException(ConfigurationException::class); | ||
|
||
$filename = '/invalid/directory/test.ini'; | ||
$data = ['app' => ['name' => 'ApplicationName', 'version' => 1]]; | ||
$this->driver->save($filename, $data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
answerToLifeUniverseEverything = 42 |