Add application info handling

This commit is contained in:
Dennis Eichhorn 2020-02-24 22:15:24 +01:00
parent 3345d63f20
commit d32c044b2e
2 changed files with 349 additions and 0 deletions

View File

@ -0,0 +1,225 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package phpOMS\Application
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Application;
use phpOMS\System\File\PathException;
use phpOMS\Utils\ArrayUtils;
/**
* Application info class.
*
* Handling the info files for modules
*
* @package phpOMS\Application
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
final class ApplicationInfo
{
/**
* File path.
*
* @var string
* @since 1.0.0
*/
private string $path = '';
/**
* Info data.
*
* @var array{name:array{id:int, internal:string, external:string}, category:string, vision:string, requirements:array, creator:array{name:string, website:string}, description:string, directory:string, dependencies:array<string, string>}|array
* @since 1.0.0
*/
private array $info = [];
/**
* Object constructor.
*
* @param string $path Info file path
*
* @since 1.0.0
*/
public function __construct(string $path)
{
$this->path = $path;
}
/**
* Get info path
*
* @return string
*
* @since 1.0.0
*/
public function getPath() : string
{
return $this->path;
}
/**
* Load info data from path.
*
* @return void
*
* @throws PathException this exception is thrown in case the info file path doesn't exist
*
* @since 1.0.0
*/
public function load() : void
{
if (!\file_exists($this->path)) {
throw new PathException($this->path);
}
$contents = \file_get_contents($this->path);
/** @var array{name:array{id:int, internal:string, external:string}, category:string, vision:string, requirements:array, creator:array{name:string, website:string}, description:string, directory:string, dependencies:array<string, string>} $info */
$info = \json_decode($contents === false ? '[]' : $contents, true);
$this->info = $info === false ? [] : $info;
}
/**
* Update info file
*
* @return void
*
* @since 1.0.0
*/
public function update() : void
{
if (!\file_exists($this->path)) {
throw new PathException($this->path);
}
\file_put_contents($this->path, \json_encode($this->info, \JSON_PRETTY_PRINT));
}
/**
* Set data
*
* @param string $path Value path
* @param mixed $data Scalar or array of data to set
* @param string $delim Delimiter of path
*
* @return void
*
* @since 1.0.0
*/
public function set(string $path, $data, string $delim = '/') : void
{
if (!\is_scalar($data) && !\is_array($data) && !($data instanceof \JsonSerializable)) {
throw new \InvalidArgumentException('Type of $data "' . \gettype($data) . '" is not supported.');
}
ArrayUtils::setArray($path, $this->info, $data, $delim, true);
}
/**
* Get info data.
*
* @return array{name:array{id:int, internal:string, external:string}, category:string, vision:string, requirements:array, creator:array{name:string, website:string}, description:string, directory:string, dependencies:array<string, string>, providing:array<string, string>, load:array<int, array{pid:string[], type:int, for:string, file:string, from:string}>}|array
*
* @since 1.0.0
*/
public function get() : array
{
return $this->info;
}
/**
* Get info data.
*
* @return int
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->info['name']['id'] ?? 0;
}
/**
* Get info data.
*
* @return string
*
* @since 1.0.0
*/
public function getInternalName() : string
{
return $this->info['name']['internal'] ?? '';
}
/**
* Get info data.
*
* @return string
*
* @since 1.0.0
*/
public function getExternalName() : string
{
return $this->info['name']['external'] ?? '';
}
/**
* Get info data.
*
* @return array<string, string>
*
* @since 1.0.0
*/
public function getDependencies() : array
{
return $this->info['dependencies'] ?? [];
}
/**
* Get info data.
*
* @return string
*
* @since 1.0.0
*/
public function getDirectory() : string
{
return $this->info['directory'] ?? '';
}
/**
* Get info category.
*
* @return string
*
* @since 1.0.0
*/
public function getCategory() : string
{
return $this->info['category'] ?? '';
}
/**
* Get info data.
*
* @return string
*
* @since 1.0.0
*/
public function getVersion() : string
{
return $this->info['version'] ?? '';
}
}

View File

@ -0,0 +1,124 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Application;
require_once __DIR__ . '/../Autoloader.php';
use phpOMS\Application\ApplicationInfo;
/**
* @testdox phpOMS\tests\Application\ApplicationInfoTest: Module info file manager
*
* @internal
*/
class ApplicationInfoTest extends \PHPUnit\Framework\TestCase
{
/**
* @testdox A info file can be correctly loaded
* @covers phpOMS\Application\ApplicationInfo
* @group framework
*/
public function testLoad() : void
{
$info = new ApplicationInfo(__DIR__ . '/info-test.json');
$info->load();
$jarray = \json_decode(\file_get_contents(__DIR__ . '/info-test.json'), true);
self::assertEquals($jarray, $info->get());
self::assertEquals($jarray['name']['id'], $info->getId());
self::assertEquals($jarray['name']['internal'], $info->getInternalName());
self::assertEquals($jarray['name']['external'], $info->getExternalName());
self::assertEquals($jarray['category'], $info->getCategory());
self::assertEquals($jarray['dependencies'], $info->getDependencies());
self::assertEquals($jarray['directory'], $info->getDirectory());
self::assertEquals($jarray['version'], $info->getVersion());
self::assertEquals(__DIR__ . '/info-test.json', $info->getPath());
}
/**
* @testdox A info file can be modified
* @covers phpOMS\Application\ApplicationInfo
* @group framework
*/
public function testChange() : void
{
$jarray = \json_decode(\file_get_contents(__DIR__ . '/info-test.json'), true);
$info = new ApplicationInfo(__DIR__ . '/info-test.json');
$info->load();
$info->set('/name/internal', 'ABC');
self::assertEquals('ABC', $info->getInternalName());
$info->update();
$info2 = new ApplicationInfo(__DIR__ . '/info-test.json');
$info2->load();
self::assertEquals($info->getInternalName(), $info2->getInternalName());
$info->set('/name/internal', $jarray['name']['internal']);
$info->update();
}
/**
* @testdox A invalid info file path load throws a PathException
* @covers phpOMS\Application\ApplicationInfo
* @group framework
*/
public function testInvalidPathLoad() : void
{
self::expectException(\phpOMS\System\File\PathException::class);
$info = new ApplicationInfo(__DIR__ . '/invalid.json');
$info->load();
}
/**
* @testdox A invalid info file path update throws a PathException
* @covers phpOMS\Application\ApplicationInfo
* @group framework
*/
public function testInvalidPathUpdate() : void
{
self::expectException(\phpOMS\System\File\PathException::class);
$info = new ApplicationInfo(__DIR__ . '/invalid.json');
$info->update();
}
/**
* @testdox A invalid change data throws a InvalidArgumentException
* @covers phpOMS\Application\ApplicationInfo
* @group framework
*/
public function testInvalidDataSet() : void
{
self::expectException(\InvalidArgumentException::class);
$info = new ApplicationInfo(__DIR__ . '/info-test.json');
$info->load();
$testObj = new class() {
public $test = 1;
public function test() : void
{
echo $this->test;
}
};
$info->set('/name/internal', $testObj);
}
}