This is specifically designed to use with Telegram Bot SDK classes.
$basePath = 'packages/telegram-bot-sdk/telegram-bot-sdk/src/Methods';
$namespace = 'Telegram\Bot\Methods';
ArrayToShapeConverter::convert($basePath, $namespace);
<?php | |
namespace App\Services; | |
use ReflectionClass; | |
use Illuminate\Support\Facades\File; | |
class ArrayToShapeConverter | |
{ | |
public function __construct(private string $basePath, private readonly string $namespace) | |
{ | |
$this->basePath = base_path($this->basePath); | |
} | |
public static function convert(string $basePath, string $namespace): void | |
{ | |
(new static($basePath, $namespace))->apply(); | |
} | |
public function apply(): void | |
{ | |
collect(File::allFiles($this->basePath)) | |
->map(fn(\SplFileInfo $file) => $file->getBasename('.php')) | |
->each(fn($class) => $this->replaceForClass($class)); | |
} | |
protected function replaceForClass(string $class): void | |
{ | |
$filename = "$this->basePath/$class.php"; | |
$fileContent = File::get($filename); | |
$namespace = "$this->namespace\\$class"; | |
$reflection = new ReflectionClass($namespace); | |
foreach ($reflection->getMethods() as $method) { | |
$docComment = $method->getDocComment(); | |
$newDoc = $this->arrayToShape($docComment); | |
$fileContent = str_replace($docComment, $newDoc, $fileContent); | |
} | |
File::put($filename, $fileContent); | |
} | |
protected function arrayToShape(string $str): string | |
{ | |
$pattern = "#\s*'(\w+)'\s*=>\s*(.+)\s*,\s*//\s*(\S+)\s*-\s*(.+)$#m"; | |
preg_match_all($pattern, $str, $matches, PREG_SET_ORDER); | |
$params = []; | |
foreach ($matches as $match) { | |
$key = trim($match[1]); | |
$type = trim($match[3]); | |
$params[] = " * \t$key: $type,"; | |
} | |
$arrayShape = implode("\n", $params); | |
$replacement = "@param array{\n$arrayShape\n * } \$params"; | |
return preg_replace("/<code>(.*?)<\/code>/s", $replacement, $str); | |
} | |
} |