- Work done to clarify a bit every section, and a hugh code refractoring also was made to the code base.

This commit is contained in:
Dave Mc Nicoll committed 2024-11-11 19:54:22 +00:00
1 parent a98e46c343
commit 6b655bdc76
15 files changed
+260 -145

No files matched your search

+34 -81
View File
@@ -15,93 +15,42 @@ class EntityDescriptor
{
use DescriptorTrait;
public string $entityTitle = <<<HTML
<div style="margin-left:15px">
<h4 class='entity-name'>%s</h4>
<div class='description'>%s</div>
<hr style="margin-top:15px">
<h5>Champs</h5>
<ol class='fields'>%s</ol>
<hr style="margin-top:15px;">
<h4 class='request-name'>%s</h4>
<h5>Requêtes</h5>
<div class='description' style="margin-bottom:10px">%s</div>
<ol class='requests'>%s</ol>
</div>
HTML;
public string $entityField = <<<HTML
<li class="odd-even">
<div style="display:flex; justify-content: space-between">
<div><strong style="font-family:monospace">$%s</strong> <span style='margin-left:15px'>%s</span></div>
</div>
<div class="field-desc" style="margin-top:10px;;background:#fff;padding:5px;font-size:0.9em">
<div style="padding:5px"><u>Champ SQL</u> : %s</div>
<div style="padding:5px"><u>Attribut</u> : %s</div>
<div style="padding:5px"><u>Type</u> : %s</div>
<div style="padding:5px"><u>Nullable</u> %s</div>
<div style="padding:5px"><u>Taille</u> : %s</div>
<div style="padding:5px"><u>Lecture seule</u> : %s</div>
</div>
</li>
HTML;
public string $searchRequestField = <<<HTML
<li class="odd-even">
<div style="display:flex; justify-content: space-between">
<div><strong style="font-family:monospace">$%s</strong> <span style='margin-left:15px'>%s</span></div>
</div>
<div class="field-desc" style="margin-top:10px;;background:#fff;padding:5px;font-size:0.9em">
<div style="padding:5px"><u>Paramètre de requête (GET)</u> : %s</div>
<div style="padding:5px"><u>Attribut</u> : %s</div>
<div style="padding:5px"><u>Type</u> : %s</div>
<div style="padding:5px"><u>Nullable</u> : %s</div>
<div style="padding:5px"><u>Valeur par défault</u> : %s</div>
</div>
</li>
HTML;
public function __construct() {}
/**
* @return Returns HTML describing entity fields
*/
public function describe(...$entities) : string
public function getEntities(...$entities) : array
{
$html = "";
$list = [];
foreach($entities as $entity) {
$propertyHtml = $searchRequestHtml = "";
$fields = [];
$entityName = is_object($entity) ? $entity::class : $entity;
$reflector = new ObjectReflection($entityName);
$table = $reflector->reflectClass()->getAttribute(Table::class);
foreach($reflector->reflectProperties() as $property) {
foreach ($reflector->reflectProperties() as $property) {
$entityField = $property->getAttribute(EntityField::class);
$field = $property->getAttribute(Field::class);
if ($field) {
$types = $property->getTypes();
$propertyHtml .= sprintf(
$this->entityField,
$property->name,
$entityField->object->description ?? "",
$field->object->name ?: $property->name,
$field->tag,
$field->object->type ?? implode(' | ', array_map(fn($e) => $e->type, $types)),
$this->yesOrNo($property->allowsNull()),
$this->length($field->object->length ?? null),
$this->yesOrNo($field->object->readonly),
);
$fields[] = [
'name' => $property->name,
'description' => $entityField->object->description ?? "",
'fieldName' => $field->object->name ?: $property->name,
'tag' => $field->tag,
'type' => $field->object->type ?? implode(' | ', array_map(fn($e) => $e->type, $types)),
'allowNulls' => $property->allowsNull(),
'length' => $field->object->length ?? null,
'readonly' => $field->object->readonly,
];
}
}
$searchFields = [];
$searchRequestReflector = new ObjectReflection($entityName::searchRequest()::class);
$searchRequestParameter = $searchRequestReflector->reflectClass()->getAttribute(SearchRequestParameter::class);
foreach($searchRequestReflector->reflectProperties() as $property) {
@@ -110,23 +59,27 @@ class EntityDescriptor
if ($field) {
$types = $property->getTypes();
$searchRequestHtml .= sprintf(
$this->searchRequestField,
$property->name,
$field->object->description,
$field->object->parameter ? implode(', ', $field->object->getParameters()) : $property->name,
$field->tag,
implode(' | ', array_map(fn($e) => $e->type, $types)),
$this->yesOrNo($property->allowsNull()),
$this->displayValue($property->value ?? "<i>aucune</i>")
);
$searchFields[] = [
'name' => $property->name,
'description' => $field->object->description,
'parameter' => $field->object->parameter ? implode(', ', $field->object->getParameters()) : $property->name,
'tag' => $field->tag,
'type' => implode(' | ', array_map(fn($e) => $e->type, $types)),
'allowNulls' => $property->allowsNull(),
'default' => $this->displayValue($property->value ?? "")
];
}
}
$html .= sprintf($this->entityTitle, $reflector->reflectClass()->getClassName(), $table->object->description ?? null, $propertyHtml, $reflector->reflectClass()->getClassName() . "::searchRequest()", $searchRequestParameter->object->description ?? "", $searchRequestHtml);
$list[$entity] = [
'className' => $reflector->reflectClass()->getClassName(),
'description' => $table->object->description ?? null,
'fields' => $fields,
'searchRequestDescription' => $searchRequestParameter->object->description ?? "",
'searchRequestFields' => $searchFields,
];
}
return $html;
return $list;
}
}
+21 -50
View File
@@ -9,46 +9,15 @@ class FormDescriptor
{
use DescriptorTrait;
public string $formTitle = <<<HTML
<div style="margin-left:15px">
<h4 style="background:#e0ecf7" class='form-name'>%s</h4>
<div class='description'>%s</div>
<hr style="margin-top:15px">
<h5>Champs</h5>
<ol class='fields'>%s</ol>
</div>
HTML;
public string $formField = <<<HTML
<li class="odd-even">
<div style="display:flex; justify-content: space-between">
<div><strong style="font-family:monospace">$%s</strong> <span style='margin-left:15px'>%s</span></div>
</div>
<div class="field-desc" style="margin-top:10px;;background:#fff;padding:5px;font-size:0.9em">
<div style="padding:5px"><u>Variable POST / champ JSON</u> : %s</div>
<div style="padding:5px"><u>Type</u> : %s</div>
<div style="padding:5px"><u>Nullable</u> : %s</div>
<div style="padding:5px"><u>Pattern regex</u> : %s</div>
<div style="padding:5px"><u>Taille min.</u> : %s</div>
<div style="padding:5px"><u>Taille max.</u> : %s</div>
<div style="padding:5px"><u>Exemple</u> : %s</div>
</div>
</li>
HTML;
/**
* @return Returns HTML describing given controller's routes
*/
public function describe(...$forms) : string
public function getForms(...$forms) : array
{
$html = "";
$list = [];
foreach($forms as $form) {
$fields = [];
$propertyHtml = "";
$entityName = is_object($form) ? $form::class : $form;
$reflector = new ObjectReflection($entityName);
$formName = is_object($form) ? $form::class : $form;
$reflector = new ObjectReflection($formName);
$context = $reflector->reflectClass()->getAttribute(ContextField::class);
@@ -57,24 +26,26 @@ class FormDescriptor
if ($field) {
$types = $property->getTypes();
$propertyHtml .= sprintf(
$this->formField,
$property->name,
$field->object->description,
$property->name,
$field->object->type ?? implode(' | ', array_map(fn($e) => $e->type, $types)),
$this->yesOrNo($property->allowsNull()),
$field->object->regexFormat ?? "aucun",
$field->object->minLength ?? "aucune",
$field->object->maxLength ?? "aucune",
$field->object->example
);
$fields[] = [
'name' => $property->name,
'description' => $field->object->description,
'type' => $field->object->type ?? implode(' | ', array_map(fn($e) => $e->type, $types)),
'allowNulls' => $property->allowsNull(),
'regexPattern' =>$field->object->regexFormat ?? "aucun",
'minLength' =>$field->object->minLength ?? "aucune",
'maxLength' =>$field->object->maxLength ?? "aucune",
'example' =>$field->object->example,
];
}
}
$html .= sprintf($this->formTitle, $reflector->reflectClass()->getClassName(), $context->object->description ?? null, $propertyHtml, );
$list[$formName] = [
'className' => $reflector->reflectClass()->getClassName(),
'description' => $context->object->description ?? null,
'fields' => $fields,
];
}
return $html;
return $list;
}
}
+11 -7
View File
@@ -8,6 +8,8 @@ use Psr\Http\Message\ResponseInterface;
trait LeanApiTrait
{
use DescriptorTrait;
#[Ignore]
public function renderMarkdown(string $filepath, array $entities = [], array $forms = [], int $code = 200, array $headers = []) : ResponseInterface
{
@@ -19,21 +21,23 @@ trait LeanApiTrait
if (str_contains($markdown, '{route:descriptor}'))
{
$describe = (new RouteDescriptor($this, $this->picea->compiler->getExtensionFromToken('url')))->describe();
$markdown = str_replace('{route:descriptor}', $describe, $markdown);
$markdown = str_replace('{route:descriptor}', $this->renderRawView('lean-api/route_descriptor', [
'routes' => (new RouteDescriptor($this, $this->picea->compiler->getExtensionFromToken('url')))->getRoutes()
]), $markdown);
}
if (str_contains($markdown, '{entity:descriptor}'))
{
$describe = (new EntityDescriptor())->describe(... $entities);
$markdown = str_replace('{entity:descriptor}', $describe, $markdown);
$markdown = str_replace('{entity:descriptor}', $this->renderRawView('lean-api/entity_descriptor', [
'entities' => (new EntityDescriptor())->getEntities(... $entities)
]), $markdown);
}
if (str_contains($markdown, '{form:descriptor}'))
{
$describe = (new FormDescriptor())->describe(... $forms);
$markdown = str_replace('{form:descriptor}', $describe, $markdown);
$markdown = str_replace('{form:descriptor}', $this->renderRawView('lean-api/form_descriptor', [
'forms' => (new FormDescriptor())->getForms(... $forms)
]), $markdown);
}
return $this->renderView("lean/layout/docs", get_defined_vars());
+11 -7
View File
@@ -22,12 +22,9 @@ HTML;
protected UrlExtension $urlExtension,
) {}
/**
* @return Returns HTML describing given controller's routes
*/
public function describe() : string
public function getRoutes() : array
{
$html = "";
$routes = [];
$reflector = new ObjectReflection($this->controller::class);
@@ -42,11 +39,18 @@ HTML;
$cleaned = $this->cleanRouteFromRegex($base.$path);
$url = $this->urlExtension->buildUrl($cleaned);
$html .= sprintf($this->routeLine, $url, $base.$path, $cleaned, $route->description, implode(', ', (array)$route->method), $route->name );
$routes[] = [
'name' => $route->name,
'route' => $url,
'path' => $base.$path,
'cleaned' => $cleaned,
'description'=> $route->description,
'methods' =>implode(', ', (array)$route->method),
];
}
}
return sprintf('<ul>%s</ul>', $html);
return $routes;
}
protected function cleanRouteFromRegex(string $route) : string