Skip to content

Commit

Permalink
Added support for setting an array and const value
Browse files Browse the repository at this point in the history
  • Loading branch information
jaxwilko committed Jan 27, 2022
1 parent 0caba9d commit 1ca70f3
Showing 1 changed file with 82 additions and 6 deletions.
88 changes: 82 additions & 6 deletions src/Config/ConfigFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public function set($key, $value = null): ConfigFile
// try to find a reference to ast object
list($target, $remaining) = $this->seek(explode('.', $key), $this->ast[0]->expr);

$valueType = $value instanceof ConfigFunction ? 'function' : gettype($value);
$valueType = $this->getType($value);

// part of a path found
if ($target && $remaining) {
Expand Down Expand Up @@ -164,7 +164,7 @@ protected function makeArrayItem(string $key, string $valueType, $value): ArrayI
? $this->makeAstArrayRecursive($key, $valueType, $value)
: new ArrayItem(
$this->makeAstNode($valueType, $value),
$this->makeAstNode(gettype($key), $key)
$this->makeAstNode($this->getType($key), $key)
);
}

Expand All @@ -173,7 +173,7 @@ protected function makeArrayItem(string $key, string $valueType, $value): ArrayI
*
* @param string $type
* @param mixed $value
* @return ConstFetch|LNumber|String_|FuncCall
* @return ConstFetch|LNumber|String_|Array_|FuncCall
*/
protected function makeAstNode(string $type, $value)
{
Expand All @@ -188,17 +188,74 @@ protected function makeAstNode(string $type, $value)
return new FuncCall(
new Name($value->getName()),
array_map(function ($arg) {
return new Arg($this->makeAstNode(gettype($arg), $arg));
return new Arg($this->makeAstNode($this->getType($arg), $arg));
}, $value->getArgs())
);
case 'const':
return new ConstFetch(new Name($value->getName()));
case 'null':
return new ConstFetch(new Name('null'));
break;
case 'array':
return $this->castArray($value);
default:
throw new \RuntimeException('not implemented replacement type: ' . $type);
}
}

/**
* Cast an array to AST
*
* @param array $array
* @return Array_
*/
protected function castArray(array $array): Array_
{
return ($caster = function ($array, $ast) use (&$caster) {
$useKeys = [];
$keys = array_keys($array);
for ($i = 0; $i < count($keys); $i++) {
$useKeys[$keys[$i]] = false;
if (!is_numeric($keys[$i]) || $keys[$i] !== $i) {
$useKeys[$keys[$i]] = true;
}
}
foreach ($array as $key => $item) {
if (is_array($item)) {
$ast->items[] = new ArrayItem(
$caster($item, new Array_()),
($useKeys[$key] ? $this->makeAstNode($this->getType($key), $key) : null)
);
continue;
}
$ast->items[] = new ArrayItem(
$this->makeAstNode($this->getType($item), $item),
($useKeys[$key] ? $this->makeAstNode($this->getType($key), $key) : null)
);
}

return $ast;
})($array, new Array_());
}

/**
* Returns type of var passed
*
* @param mixed $var
* @return string
*/
protected function getType($var): string
{
if ($var instanceof ConfigFunction) {
return 'function';
}

if ($var instanceof ConfigConst) {
return 'const';
}

return gettype($var);
}

/**
* Returns an ArrayItem generated from a dot notation path
*
Expand All @@ -217,7 +274,7 @@ protected function makeAstArrayRecursive(string $key, string $valueType, $value)
if (is_numeric($pathKey)) {
$pathKey = (int) $pathKey;
}
$arrayItem = new ArrayItem($arrayItem, $this->makeAstNode(gettype($pathKey), $pathKey));
$arrayItem = new ArrayItem($arrayItem, $this->makeAstNode($this->getType($pathKey), $pathKey));

if ($index !== array_key_last($path)) {
$arrayItem = new Array_([$arrayItem]);
Expand All @@ -235,6 +292,7 @@ protected function makeAstArrayRecursive(string $key, string $valueType, $value)
* @param $pointer
* @param int $depth
* @return array
* @throws SystemException
*/
protected function seek(array $path, &$pointer, int $depth = 0): array
{
Expand Down Expand Up @@ -329,11 +387,29 @@ public function write(string $filePath = null): void
file_put_contents($filePath, $this->render());
}

/**
* Returns a new instance of ConfigFunction
*
* @param string $name
* @param array $args
* @return ConfigFunction
*/
public function function(string $name, array $args): ConfigFunction
{
return new ConfigFunction($name, $args);
}

/**
* Returns a new instance of ConfigConst
*
* @param string $name
* @return ConfigConst
*/
public function const(string $name): ConfigConst
{
return new ConfigConst($name);
}

/**
* Get the printed AST as php code
*
Expand Down

0 comments on commit 1ca70f3

Please sign in to comment.