diff --git a/Application/ApplicationInfo.php b/Application/ApplicationInfo.php index e69de29bb..9a7e6207b 100644 --- a/Application/ApplicationInfo.php +++ b/Application/ApplicationInfo.php @@ -0,0 +1,225 @@ +}|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} $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, providing:array, load:array}|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 + * + * @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'] ?? ''; + } +} diff --git a/tests/Application/ApplicationInfoTest.php b/tests/Application/ApplicationInfoTest.php new file mode 100644 index 000000000..30a318586 --- /dev/null +++ b/tests/Application/ApplicationInfoTest.php @@ -0,0 +1,124 @@ +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); + } +}