Skip to content

Instantly share code, notes, and snippets.

@irazasyed
Last active May 17, 2023 18:30
Show Gist options
  • Save irazasyed/b1ef8c4a9e6e2fc9e96de7ab9595e426 to your computer and use it in GitHub Desktop.
Save irazasyed/b1ef8c4a9e6e2fc9e96de7ab9595e426 to your computer and use it in GitHub Desktop.
PHP: Array to ArrayShape Converter for PHPDocs

Array to ArrayShape Converter

This is specifically designed to use with Telegram Bot SDK classes.

Usage

$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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment