Skip to content

Instantly share code, notes, and snippets.

@RajithaKumara
Last active November 1, 2023 13:18
Show Gist options
  • Save RajithaKumara/37f006b44342fdef6a58038a377e432a to your computer and use it in GitHub Desktop.
Save RajithaKumara/37f006b44342fdef6a58038a377e432a to your computer and use it in GitHub Desktop.
Generate PHP doc comment for zircote/swagger-php from OpenAPI json

Motivation

Convert PHP API doc source from APIDOC to swagger-php.

Steps

  • Generate OpenAPI definition from APIDOC doc comments
  • Generate swagger-php annotations using generate-doc-comment.php script.
<?php
ini_set('xdebug.var_display_max_depth', '-1');
ini_set('xdebug.var_display_max_children', '-1');
ini_set('xdebug.var_display_max_data', '-1');
require_once(__DIR__ . "/vendor/autoload.php");
use OpenApi\Annotations as OA;
use OpenApi\Serializer;
$serializer = new Serializer();
$openapi = $serializer->deserializeFile(__DIR__ . '/openapi.json', 'OpenApi\Annotations\OpenApi');
$definitions = $openapi->jsonSerialize();
$keys = get_object_vars($definitions);
foreach ($keys as $key => $definition) {
$comment = '';
if ($key === 'openapi') {
continue;
} elseif ($key === 'info') {
$comment = createStringFromProperties($definition);
// $comment = getInfoComment($definition);
} elseif ($key === 'servers') {
$serversString = [];
foreach ($definition as $server) {
$serversString[] = createStringFromProperties($server);
// $serversString[] = getServerComment($server);
}
$comment = implode("\n * ", $serversString);
} elseif ($key === 'paths') {
$pathsStrings = getPathsComment($definition);
$comment = implode("\n * ", $pathsStrings);
} elseif ($key === 'components') {
} elseif ($key === 'tags') {
} elseif ($key === 'externalDocs') {
}
file_put_contents(
__DIR__ . "/openapi-{$key}.php",
"<?php
use OpenApi\Annotations as OA;
/**
*
* {$comment}
*
*/
"
);
}
function getPathsComment($pathsObject)
{
$paths = getProperties($pathsObject);
$pathOperations = [];
foreach ($paths as $path => $pathObject) {
$operations = getPathComment($path, $pathObject);
$pathOperations = array_merge($pathOperations, $operations);
}
return $pathOperations;
}
function getPathComment($path, $definition)
{
$operations = getProperties($definition);
$operationString = [];
foreach ($operations as $method => $operation) {
$operationString[] = getOperationComment($path, $operation);
}
return $operationString;
}
function getOperationComment($path, $operation)
{
$method = 'Get';
if ($operation instanceof OA\Operation) {
$fqcName = get_class($operation);
$method = str_replace('OpenApi\Annotations\\', '', $fqcName);
}
$properties = getProperties($operation);
unset($properties['method']);
return "@OA\\{$method}(path=\"{$path}\", " . createStringFromProperties($properties) . ")";
}
function getServerComment($serverObject)
{
return "@OA\Server(" . createStringFromProperties(getProperties($serverObject)) . ")";
}
function getInfoComment($infoObject)
{
return "@OA\Info(" . createStringFromProperties(getProperties($infoObject)) . ")";
}
function createStringFromProperties($properties)
{
if ($properties instanceof OA\AbstractAnnotation) {
$fqcName = get_class($properties);
$className = str_replace('OpenApi\Annotations\\', '', $fqcName);
return "@OA\\{$className}(" . createStringFromProperties(getProperties($properties)) . ")";
} elseif (is_array($properties)) {
return implode(
', ',
array_map(
function ($k, $v) {
if (!is_string($v) || !is_numeric($v)) {
if (is_array($v)) {
$array = [];
$isAnnotationArray = true;
foreach ($v as $obj) {
if ($obj instanceof OA\AbstractAnnotation) {
$array[] = createStringFromProperties($obj);
} else {
$array[] = createStringFromProperties(getProperties($obj));
$isAnnotationArray = false;
}
}
if ($isAnnotationArray) {
return implode(', ', $array);
}
$v = "{" . implode(', ', $array) . "}";
} elseif ($v instanceof OA\AbstractAnnotation) {
return createStringFromProperties($v);
} else {
$v = json_encode($v);
}
return sprintf('%s=%s', $k, $v);
}
return sprintf('%s="%s"', $k, $v);
},
array_keys($properties),
$properties
)
);
}
return $properties;
}
function getProperties($object)
{
if (is_string($object) || is_numeric($object) || is_bool($object)) {
return "\"{$object}\"";
}
if (!is_array($object)) {
$object = get_object_vars($object);
}
$properties = [];
foreach ($object as $defKey => $def) {
if ($defKey === '_context' || $defKey === '_unmerged') {
continue;
} elseif ($def !== OA\UNDEFINED) {
$properties[$defKey] = $def;
}
}
return $properties;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment