getMessage(), $e->getCode()); } return new self($settings); } /** * Returns full path to settings file * * @return string */ public static function filepath(): string { return self::$filepath; } /** * @param object $settings * @throws JsonException */ protected function __construct(object $settings) { foreach ($settings->directories ?? [] as $path) { $this->addDirPath($path); } foreach ($settings->files ?? [] as $path) { $this->addFilePath($path); } $this->setDevMode(!empty($settings->devMode)); $this->setPreserveOutput(!empty($settings->preserveOutput)); isset($settings->environment) && $this->setEnvFilepath($settings->environment); isset($settings->output) && $this->setOutputPath($settings->output); foreach ($settings->formats ?? [] as $format) { $this->addFormat(ConvertFormat::fromArg($format)); } foreach ($settings->vars ?? [] as $name => $value) { $this->vars[$name] = $value; } } /** * @param string $path * @return void * @throws JsonException */ public function addDirPath(string $path): void { $this->directories = array_unique(array_merge( $this->directories ?? [], [FileSystem::normalizePath($path)] )); $files = array_filter( FileSystem::dirContents($path), static fn ($filename) => FileSystem::isCollectionFile($filename) ); $this->collectionPaths = array_unique(array_merge($this->collectionPaths ?? [], $files)); } /** * @param string $path * @return void * @throws JsonException */ public function addFilePath(string $path): void { $normpath = FileSystem::normalizePath($path); if (!FileSystem::isCollectionFile($normpath)) { throw new InvalidArgumentException("not a valid collection: $path"); } in_array($path, $this->collectionPaths) || $this->collectionPaths[] = $path; } /** * @param string $outputPath * @return void */ public function setOutputPath(string $outputPath): void { $this->outputPath = $outputPath; } /** * @param bool $devMode * @return void */ public function setDevMode(bool $devMode): void { $this->devMode = $devMode; } /** * @param ConvertFormat $format * @return void */ public function addFormat(ConvertFormat $format): void { $this->formats[$format->name] = $format; } /** * Returns array of variables * * @return string[] */ public function vars(): array { return $this->vars; } /** * @param bool $preserveOutput * @return void */ public function setPreserveOutput(bool $preserveOutput): void { $this->preserveOutput = $preserveOutput; } /** * @param string $filepath * @return void */ public function setEnvFilepath(string $filepath): void { $this->envFilepath = FileSystem::normalizePath($filepath); } /** * @return bool */ public function isDevMode(): bool { return $this->devMode; } /** * @return string[] */ public function collectionPaths(): array { return $this->collectionPaths; } /** * @return string */ public function outputPath(): string { return $this->outputPath; } /** * @return bool */ public function isPreserveOutput(): bool { return $this->preserveOutput; } /** * @return ConvertFormat[] */ public function formats(): array { return $this->formats; } /** * @return string */ public function envFilepath(): string { return $this->envFilepath; } /** * Determines fieldset of settings JSON * * @return array */ public function __serialize(): array { return [ 'dev' => $this->isDevMode(), 'directories' => $this->directories, 'files' => $this->collectionPaths(), 'environment' => $this->envFilepath(), 'output' => $this->outputPath(), 'preserve-output' => $this->isPreserveOutput(), 'formats' => array_values(array_map( static fn (ConvertFormat $format) => $format->toArg(), $this->formats(), )), 'vars' => $this->vars, ]; } /** * Converts settings into JSON format * * @return string */ public function __toString(): string { return json_encode($this->__serialize(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } /** * Writes settings in JSON format into settings file * * @param array $vars * @return bool */ public function dump(array $vars = []): bool { count($vars) > 0 && $this->vars = $vars; return file_put_contents(self::$filepath, (string)$this) > 0; } /** * Makes a backup file of current settings file * * @return string */ public function backup(): string { copy(self::$filepath, $newfilepath = self::$filepath . '.bak.' . time()); return $newfilepath; } }