nodeFactory = $nodeFactory; $this->implodeAnalyzer = $implodeAnalyzer; $this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser; } public function createFromJsonString(string $stringValue) : \PhpParser\Node\Expr\Array_ { $array = \RectorPrefix20210816\Nette\Utils\Json::decode($stringValue, \RectorPrefix20210816\Nette\Utils\Json::FORCE_ARRAY); return $this->nodeFactory->createArray($array); } /** * @param Expr[] $placeholderNodes */ public function createFromJsonStringAndPlaceholders(string $jsonString, array $placeholderNodes) : \PhpParser\Node\Expr\Array_ { $jsonArray = $this->createFromJsonString($jsonString); $this->replaceNodeObjectHashPlaceholdersWithNodes($jsonArray, $placeholderNodes); return $jsonArray; } /** * @param Expr[] $placeholderNodes */ private function replaceNodeObjectHashPlaceholdersWithNodes(\PhpParser\Node\Expr\Array_ $array, array $placeholderNodes) : void { // traverse and replace placeholder by original nodes $this->simpleCallableNodeTraverser->traverseNodesWithCallable($array, function (\PhpParser\Node $node) use($placeholderNodes) : ?Expr { if ($node instanceof \PhpParser\Node\Expr\Array_ && \count($node->items) === 1) { $onlyItem = $node->items[0]; if (!$onlyItem instanceof \PhpParser\Node\Expr\ArrayItem) { throw new \Rector\Core\Exception\ShouldNotHappenException(); } $placeholderNode = $this->matchPlaceholderNode($onlyItem->value, $placeholderNodes); if ($placeholderNode && $this->implodeAnalyzer->isImplodeToJson($placeholderNode)) { /** @var FuncCall $placeholderNode */ return $placeholderNode->args[1]->value; } } return $this->matchPlaceholderNode($node, $placeholderNodes); }); } /** * @param Expr[] $placeholderNodes */ private function matchPlaceholderNode(\PhpParser\Node $node, array $placeholderNodes) : ?\PhpParser\Node\Expr { if (!$node instanceof \PhpParser\Node\Scalar\String_) { return null; } return $placeholderNodes[$node->value] ?? null; } }