Skip to content

Commit

Permalink
Code: add types
Browse files Browse the repository at this point in the history
  • Loading branch information
f3l1x committed Nov 17, 2023
1 parent ba69eea commit 75509f9
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 125 deletions.
2 changes: 1 addition & 1 deletion ruleset.xml
Expand Up @@ -2,7 +2,7 @@
<ruleset name="Contributte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
<!-- Rulesets -->
<rule ref="./vendor/contributte/qa/ruleset-8.0.xml">
<exclude name="SlevomatCodingStandard.PHP.DisallowReference.DisallowedPassingByReference"/>
<exclude name="Squiz.Strings.DoubleQuoteUsage.ContainsVar"/>
</rule>

<!-- Rules -->
Expand Down
60 changes: 25 additions & 35 deletions src/DI/ApiDocuExtension.php
@@ -1,6 +1,4 @@
<?php

declare(strict_types=1);
<?php declare(strict_types = 1);

namespace Contributte\ApiDocu\DI;

Expand All @@ -9,51 +7,49 @@
use Nette\DI\CompilerExtension;
use Nette\DI\Helpers;
use Nette\PhpGenerator\ClassType;
use Nette\Schema\Expect;
use Nette\Schema\Schema;
use stdClass;

/**
* @property-read stdClass $config
*/
class ApiDocuExtension extends CompilerExtension
{

/**
* @var array<mixed>
*/
protected $config;

/**
* @var array<string|array<null>>
*/
private $defaults = [
'apiDir' => '%wwwDir%/api',
'httpAuth' => [
'user' => null,
'password' => null,
],
];

public function getConfigSchema(): Schema
{
return Expect::structure([
'apiDir' => Expect::string()->default('%wwwDir%/api'),
'httpAuth' => Expect::structure([
'user' => Expect::string(),
'password' => Expect::string(),
]),
]);
}

public function loadConfiguration(): void
{
$this->config = $this->prepareConfig();
}


public function beforeCompile(): void
{
$builder = $this->getContainerBuilder();
$config = $this->config;

$builder->addDefinition($this->prefix('generator'))
->setClass(Generator::class)
->setArguments([$config['apiDir'], $config['httpAuth']]);
->setType(Generator::class)
->setArguments([$config->apiDir, (array) $config->httpAuth]);

$builder->addDefinition($this->prefix('starter'))
->setClass(Starter::class)
->setType(Starter::class)
->setArguments([
$builder->getDefinition($this->prefix('generator')),
$builder->getDefinition('router'),
]);
}


public function afterCompile(ClassType $class): void
{
parent::afterCompile($class);
Expand All @@ -64,19 +60,13 @@ public function afterCompile(ClassType $class): void
);
}


/**
* @return array<mixed>
*/
protected function prepareConfig(): array
protected function prepareConfig(): stdClass
{
$config = $this->validateConfig($this->defaults, $this->config);

$config['apiDir'] = Helpers::expand(
$config['apiDir'],
$this->getContainerBuilder()->parameters
);
/** @var stdClass $config */
$config = $this->getConfig();
$config->apiDir = Helpers::expand($config->apiDir, $this->getContainerBuilder()->parameters);

return $config;
}

}
91 changes: 33 additions & 58 deletions src/Generator.php
@@ -1,58 +1,45 @@
<?php

declare(strict_types=1);
<?php declare(strict_types = 1);

namespace Contributte\ApiDocu;

use Contributte\ApiRouter\ApiRoute;
use Nette\Application\IRouter;
use Nette\Application\Routers\RouteList;
use Nette\Application\UI\ITemplateFactory;
use Nette\Application\UI\TemplateFactory;
use Nette\Bridges\ApplicationLatte\DefaultTemplate;
use Nette\Bridges\ApplicationLatte\Template;
use Nette\Http;
use Nette\Http\Request;
use Nette\Routing\Router;
use Tracy\Debugger;

class Generator
{

/**
* @var ITemplateFactory
*/
private $templateFactory;
private TemplateFactory $templateFactory;

/**
* @var Http\Request
*/
private $httpRequest;
private Request $httpRequest;

/**
* @var string
*/
private $appDir;
private string $appDir;

/**
* @var array<mixed>
*/
private $httpAuth;
/** @var array{user: ?string, password: ?string} */
private array $httpAuth;

/**
* @param array<mixed> $httpAuth
* @param array{user: ?string, password: ?string} $httpAuth
*/
public function __construct(
string $appDir,
array $httpAuth,
ITemplateFactory $templateFactory,
Http\Request $httpRequest
) {
TemplateFactory $templateFactory,
Request $httpRequest
)
{
$this->appDir = $appDir;
$this->httpAuth = $httpAuth;
$this->templateFactory = $templateFactory;
$this->httpRequest = $httpRequest;
}


public function generateAll(IRouter $router): void
public function generateAll(Router $router): void
{
$sections = $this->splitRoutesIntoSections($router);

Expand All @@ -71,7 +58,7 @@ public function generateAll(IRouter $router): void
foreach ($sections as $sectionName => $routes) {
if (is_array($routes)) {
foreach ($routes as $fileName => $route) {
$this->generateOne($route, $sections, "$sectionName.$fileName");
$this->generateOne($route, $sections, $sectionName . '.' . $fileName);
}
} else {
$this->generateOne($routes, $sections, (string) $sectionName);
Expand All @@ -95,7 +82,7 @@ public function generateTarget(ApiRoute $route, array $parameters): void
'httpRequest' => $this->httpRequest,
]);

if (class_exists('Tracy\Debugger')) {
if (class_exists(Debugger::class)) {
Debugger::$productionMode = true;
}

Expand Down Expand Up @@ -139,7 +126,6 @@ public function generateIndex(array $sections): void
);
}


public function generateSuccess(): void
{
/** @var DefaultTemplate $template */
Expand All @@ -149,32 +135,25 @@ public function generateSuccess(): void
'apiDir' => $this->appDir,
]);

if (class_exists('Tracy\Debugger')) {
if (class_exists(Debugger::class)) {
Debugger::$productionMode = true;
}

echo (string) $template;
}


public function createTemplate(string $which): Template
{
/** @var DefaultTemplate|null $template */
$template = $this->templateFactory->createTemplate();

if (!$template instanceof Template) {
throw new \UnexpectedValueException;
}
assert($template instanceof DefaultTemplate);

$template->addFilter(null, 'Contributte\ApiDocu\TemplateFilters::common');

$template->setFile(__DIR__ . '/templates/' . $which);

$template->setParameters(['base_dir' => __DIR__ . '/templates']);

$template->addFilter('routeMaskStyles', function ($mask): string {
return str_replace(['<', '>'], ['<span class="apiDocu-mask-param">&lt;', '&gt;</span>'], $mask);
});
$template->addFilter('routeMaskStyles', fn ($mask): string => str_replace(['<', '>'], ['<span class="apiDocu-mask-param">&lt;', '&gt;</span>'], $mask));

$template->addFilter('apiDocuResponseCode', function ($code): string {
if ($code >= 200 && $code <= 202) {
Expand All @@ -197,31 +176,28 @@ public function createTemplate(string $which): Template


/********************************************************************************
* INTERNAL *
* INTERNAL *
********************************************************************************/

/**
* @return array<mixed>
* @return array<int<1,max>|string, array<int,ApiRoute>|ApiRoute>
*/
private function splitRoutesIntoSections(IRouter $router): array
private function splitRoutesIntoSections(Router $router): array
{
$routes = [];
$sections = [];
$fileName = 1;

if ($router instanceof ApiRoute) {
$routes = [$router];
} elseif ($router instanceof \IteratorAggregate) {
} elseif ($router instanceof RouteList) {
$routes = $this->getApiRoutesFromIterator($router);
}

foreach ($routes as $route) {
if ($route->getSection()) {
if ($sections !== [] && $sections[$route->getSection()] === []) {
$sections[$route->getSection()] = [];
}

$sections[$route->getSection()][$fileName] = $route;
if ($route->getSection() !== null) {
$sections[$route->getSection()] ??= [];
$sections[$route->getSection()][$fileName] = $route; // @phpstan-ignore-line
} else {
$sections[$fileName] = $route;
}
Expand All @@ -232,21 +208,20 @@ private function splitRoutesIntoSections(IRouter $router): array
return $sections;
}


/**
* Recursively flatten \IteratorAggregate (probably Nette\Application\Routers\RouteList)
* @return array<mixed>
*
* @return array<ApiRoute>
*/
private function getApiRoutesFromIterator(\IteratorAggregate $i): array
private function getApiRoutesFromIterator(RouteList $routeList): array
{
$return = [];
$routers = $routeList->getRouters();

/** @var RouteList $i */
$routers = $i->getRouters();
foreach ($routers as $router) {
if ($router instanceof ApiRoute) {
$return[] = $router;
} elseif ($router instanceof \IteratorAggregate) {
} elseif ($router instanceof RouteList) {
$routes = $this->getApiRoutesFromIterator($router);

foreach ($routes as $route) {
Expand All @@ -258,7 +233,6 @@ private function getApiRoutesFromIterator(\IteratorAggregate $i): array
return $return;
}


private function getHttpAuthSnippet(): string
{
$user = (string) $this->httpAuth['user'];
Expand All @@ -277,4 +251,5 @@ private function getHttpAuthSnippet(): string
. " die('Invalid authentication');"
. '} ?>';
}

}

0 comments on commit 75509f9

Please sign in to comment.