mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 23:59:26 +03:00
Refactoring including assets
This commit is contained in:
parent
5124f07ece
commit
9cb6006b69
@ -12,30 +12,82 @@
|
|||||||
namespace Nelmio\ApiDocBundle\Render\Html;
|
namespace Nelmio\ApiDocBundle\Render\Html;
|
||||||
|
|
||||||
use Symfony\Bridge\Twig\Extension\AssetExtension;
|
use Symfony\Bridge\Twig\Extension\AssetExtension;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
class GetNelmioAsset
|
class GetNelmioAsset
|
||||||
{
|
{
|
||||||
private $assetExtension;
|
private $assetExtension;
|
||||||
private $defaultAssetsMode;
|
private $resourcesDir;
|
||||||
|
private $cdnUrl;
|
||||||
|
private $assetsMode = AssetsMode::BUNDLE;
|
||||||
|
|
||||||
public function __construct(AssetExtension $assetExtension, $defaultAssetsMode)
|
public function __construct(AssetExtension $assetExtension)
|
||||||
{
|
{
|
||||||
$this->assetExtension = $assetExtension;
|
$this->assetExtension = $assetExtension;
|
||||||
$this->defaultAssetsMode = $defaultAssetsMode;
|
$this->cdnUrl = 'https://cdn.jsdelivr.net/gh/nelmio/NelmioApiDocBundle/Resources/public';
|
||||||
|
$this->resourcesDir = __DIR__.'/../../Resources/public';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke($asset, $forcedMode = null)
|
public function toTwigFunction($assetsMode): TwigFunction
|
||||||
{
|
{
|
||||||
$mode = $forcedMode ?: $this->defaultAssetsMode;
|
$this->assetsMode = $assetsMode;
|
||||||
if (AssetsMode::CDN === $mode) {
|
|
||||||
return sprintf(
|
return new TwigFunction('nelmioAsset', $this, ['is_safe' => ['html']]);
|
||||||
'https://cdn.jsdelivr.net/gh/nelmio/NelmioApiDocBundle@4.1/Resources/public/%s',
|
}
|
||||||
$asset
|
|
||||||
);
|
public function __invoke($asset)
|
||||||
} elseif (AssetsMode::OFFLINE === $mode) {
|
{
|
||||||
return file_get_contents(__DIR__.sprintf('/../../Resources/public/%s', $asset));
|
[$extension, $mode] = $this->getExtension($asset);
|
||||||
|
[$resource, $isInline] = $this->getResource($asset, $mode);
|
||||||
|
if ('js' == $extension) {
|
||||||
|
return $this->renderJavascript($resource, $isInline);
|
||||||
|
} elseif ('css' == $extension) {
|
||||||
|
return $this->renderCss($resource, $isInline);
|
||||||
} else {
|
} else {
|
||||||
return $this->assetExtension->getAssetUrl(sprintf('bundles/nelmioapidoc/%s', $asset));
|
return $resource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getExtension($asset)
|
||||||
|
{
|
||||||
|
$extension = mb_substr($asset, -3, 3, 'utf-8');
|
||||||
|
if ('.js' === $extension) {
|
||||||
|
return ['js', $this->assetsMode];
|
||||||
|
} elseif ('png' === $extension) {
|
||||||
|
return ['png', AssetsMode::OFFLINE == $this->assetsMode ? AssetsMode::CDN : $this->assetsMode];
|
||||||
|
} else {
|
||||||
|
return ['css', $this->assetsMode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getResource($asset, $mode)
|
||||||
|
{
|
||||||
|
if (filter_var($asset, FILTER_VALIDATE_URL)) {
|
||||||
|
return [$asset, false];
|
||||||
|
} elseif (AssetsMode::OFFLINE === $mode) {
|
||||||
|
return [file_get_contents($this->resourcesDir.'/'.$asset), true];
|
||||||
|
} elseif (AssetsMode::CDN === $mode) {
|
||||||
|
return [$this->cdnUrl.'/'.$asset, false];
|
||||||
|
} else {
|
||||||
|
return [$this->assetExtension->getAssetUrl(sprintf('bundles/nelmioapidoc/%s', $asset)), false];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderJavascript(string $script, bool $isInline)
|
||||||
|
{
|
||||||
|
if ($isInline) {
|
||||||
|
return sprintf('<script>%s</script>', $script);
|
||||||
|
} else {
|
||||||
|
return sprintf('<script src="%s"></script>', $script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderCss(string $stylesheet, bool $isInline)
|
||||||
|
{
|
||||||
|
if ($isInline) {
|
||||||
|
return sprintf('<style>%s</style>', $stylesheet);
|
||||||
|
} else {
|
||||||
|
return sprintf('<link rel="stylesheet" href="%s">', $stylesheet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,28 +16,23 @@ use Nelmio\ApiDocBundle\Render\OpenApiRenderer;
|
|||||||
use Nelmio\ApiDocBundle\Render\RenderOpenApi;
|
use Nelmio\ApiDocBundle\Render\RenderOpenApi;
|
||||||
use OpenApi\Annotations\OpenApi;
|
use OpenApi\Annotations\OpenApi;
|
||||||
use OpenApi\Annotations\Server;
|
use OpenApi\Annotations\Server;
|
||||||
use Symfony\Bridge\Twig\Extension\AssetExtension;
|
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
use Twig\TwigFunction;
|
|
||||||
|
|
||||||
class HtmlOpenApiRenderer implements OpenApiRenderer
|
class HtmlOpenApiRenderer implements OpenApiRenderer
|
||||||
{
|
{
|
||||||
/**
|
/** @var Environment|\Twig_Environment */
|
||||||
* @var Environment|\Twig_Environment
|
|
||||||
*/
|
|
||||||
private $twig;
|
private $twig;
|
||||||
/**
|
|
||||||
* @var AssetExtension
|
|
||||||
*/
|
|
||||||
private $assetExtension;
|
|
||||||
|
|
||||||
public function __construct($twig, AssetExtension $assetExtension)
|
/** @var GetNelmioAsset */
|
||||||
|
private $getNelmioAsset;
|
||||||
|
|
||||||
|
public function __construct($twig, GetNelmioAsset $getNelmioAsset)
|
||||||
{
|
{
|
||||||
if (!$twig instanceof \Twig_Environment && !$twig instanceof Environment) {
|
if (!$twig instanceof \Twig_Environment && !$twig instanceof Environment) {
|
||||||
throw new InvalidArgumentException(sprintf('Providing an instance of "%s" as twig is not supported.', get_class($twig)));
|
throw new InvalidArgumentException(sprintf('Providing an instance of "%s" as twig is not supported.', get_class($twig)));
|
||||||
}
|
}
|
||||||
$this->twig = $twig;
|
$this->twig = $twig;
|
||||||
$this->assetExtension = $assetExtension;
|
$this->getNelmioAsset = $getNelmioAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormat(): string
|
public function getFormat(): string
|
||||||
@ -53,12 +48,7 @@ class HtmlOpenApiRenderer implements OpenApiRenderer
|
|||||||
'swagger_ui_config' => [],
|
'swagger_ui_config' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->twig->addFunction(
|
$this->twig->addFunction($this->getNelmioAsset->toTwigFunction($options['assets_mode']));
|
||||||
new TwigFunction(
|
|
||||||
'nelmioAsset',
|
|
||||||
new GetNelmioAsset($this->assetExtension, $options['assets_mode'])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this->twig->render(
|
return $this->twig->render(
|
||||||
'@NelmioApiDoc/SwaggerUi/index.html.twig',
|
'@NelmioApiDoc/SwaggerUi/index.html.twig',
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
</service>
|
</service>
|
||||||
<service id="nelmio_api_doc.render_docs.html" class="Nelmio\ApiDocBundle\Render\Html\HtmlOpenApiRenderer" public="false">
|
<service id="nelmio_api_doc.render_docs.html" class="Nelmio\ApiDocBundle\Render\Html\HtmlOpenApiRenderer" public="false">
|
||||||
<argument type="service" id="twig" />
|
<argument type="service" id="twig" />
|
||||||
|
<argument type="service" id="nelmio_api_doc.render_docs.html.asset" />
|
||||||
|
</service>
|
||||||
|
<service id="nelmio_api_doc.render_docs.html.asset" class="Nelmio\ApiDocBundle\Render\Html\GetNelmioAsset" public="false">
|
||||||
<argument type="service" id="twig.extension.assets" />
|
<argument type="service" id="twig.extension.assets" />
|
||||||
</service>
|
</service>
|
||||||
<service id="nelmio_api_doc.render_docs.json" class="Nelmio\ApiDocBundle\Render\Json\JsonOpenApiRenderer" public="false">
|
<service id="nelmio_api_doc.render_docs.json" class="Nelmio\ApiDocBundle\Render\Json\JsonOpenApiRenderer" public="false">
|
||||||
|
@ -14,13 +14,8 @@ file that was distributed with this source code. #}
|
|||||||
<title>{% block title %}{{ swagger_data.spec.info.title }}{% endblock title %}</title>
|
<title>{% block title %}{{ swagger_data.spec.info.title }}{% endblock title %}</title>
|
||||||
|
|
||||||
{% block stylesheets %}
|
{% block stylesheets %}
|
||||||
{% if assets_mode == 'offline' %}
|
{{ nelmioAsset('swagger-ui/swagger-ui.css') }}
|
||||||
<style>{{ nelmioAsset('swagger-ui/swagger-ui.css')|raw }}</style>
|
{{ nelmioAsset('style.css') }}
|
||||||
<style>{{ nelmioAsset('style.css')|raw }}</style>
|
|
||||||
{% else %}
|
|
||||||
<link rel="stylesheet" href="{{ nelmioAsset('swagger-ui/swagger-ui.css') }}">
|
|
||||||
<link rel="stylesheet" href="{{ nelmioAsset('style.css.css') }}">
|
|
||||||
{% endif %}
|
|
||||||
{% endblock stylesheets %}
|
{% endblock stylesheets %}
|
||||||
|
|
||||||
{% block swagger_data %}
|
{% block swagger_data %}
|
||||||
@ -59,11 +54,7 @@ file that was distributed with this source code. #}
|
|||||||
<header>
|
<header>
|
||||||
{% block header %}
|
{% block header %}
|
||||||
<a id="logo" href="https://github.com/nelmio/NelmioApiDocBundle">
|
<a id="logo" href="https://github.com/nelmio/NelmioApiDocBundle">
|
||||||
{% if assets_mode in ['offline', 'cdn'] %}
|
|
||||||
<img src="{{ nelmioAsset('logo.png', 'cdn') }}" alt="NelmioApiDocBundle">
|
|
||||||
{% else %}
|
|
||||||
<img src="{{ nelmioAsset('logo.png') }}" alt="NelmioApiDocBundle">
|
<img src="{{ nelmioAsset('logo.png') }}" alt="NelmioApiDocBundle">
|
||||||
{% endif %}
|
|
||||||
</a>
|
</a>
|
||||||
{% endblock header %}
|
{% endblock header %}
|
||||||
</header>
|
</header>
|
||||||
@ -73,20 +64,11 @@ file that was distributed with this source code. #}
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block javascripts %}
|
{% block javascripts %}
|
||||||
{% if assets_mode == 'offline' %}
|
{{ nelmioAsset('swagger-ui/swagger-ui-bundle.js') }}
|
||||||
<script>{{ nelmioAsset('swagger-ui/swagger-ui-bundle.js')|raw }}</script>
|
{{ nelmioAsset('swagger-ui/swagger-ui-standalone-preset.js') }}
|
||||||
<script>{{ nelmioAsset('swagger-ui/swagger-ui-standalone-preset.js')|raw }}</script>
|
|
||||||
{% else %}
|
|
||||||
<script src="{{ nelmioAsset('swagger-ui/swagger-ui-bundle.js') }}"></script>
|
|
||||||
<script src="{{ nelmioAsset('swagger-ui/swagger-ui-standalone-preset.js') }}"></script>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock javascripts %}
|
{% endblock javascripts %}
|
||||||
|
|
||||||
{% if assets_mode == 'offline' %}
|
{{ nelmioAsset('init-swagger-ui.js') }}
|
||||||
<script>{{ nelmioAsset('init-swagger-ui.js')|raw }}</script>
|
|
||||||
{% else %}
|
|
||||||
<script src="{{ nelmioAsset('init-swagger-ui.js') }}"></script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% block swagger_initialization %}
|
{% block swagger_initialization %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
112
Tests/Render/Html/GetNelmioAssetTest.php
Normal file
112
Tests/Render/Html/GetNelmioAssetTest.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Render\Html;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\Render\Html\AssetsMode;
|
||||||
|
use Nelmio\ApiDocBundle\Render\Html\GetNelmioAsset;
|
||||||
|
use Nelmio\ApiDocBundle\Tests\Functional\WebTestCase;
|
||||||
|
|
||||||
|
class GetNelmioAssetTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/** @dataProvider provideAsset */
|
||||||
|
public function test($mode, $asset, $expectedContent)
|
||||||
|
{
|
||||||
|
static::bootKernel();
|
||||||
|
/** @var GetNelmioAsset $getNelmioAsset */
|
||||||
|
$getNelmioAsset = self::getContainer()->get('nelmio_api_doc.render_docs.html.asset');
|
||||||
|
$twigFunction = $getNelmioAsset->toTwigFunction($mode);
|
||||||
|
self::assertSame($expectedContent, $twigFunction->getCallable()->__invoke($asset, $mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideAsset()
|
||||||
|
{
|
||||||
|
$cdnDir = 'https://cdn.jsdelivr.net/gh/nelmio/NelmioApiDocBundle/Resources/public';
|
||||||
|
$resourceDir = __DIR__.'/../../../Resources/public';
|
||||||
|
|
||||||
|
return $this->provideCss($cdnDir, $resourceDir)
|
||||||
|
+ $this->provideJs($cdnDir, $resourceDir)
|
||||||
|
+ $this->provideImage($cdnDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function provideCss($cdnDir, $resourceDir)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'bundled css' => [
|
||||||
|
AssetsMode::BUNDLE,
|
||||||
|
'style.css',
|
||||||
|
'<link rel="stylesheet" href="/bundles/nelmioapidoc/style.css">',
|
||||||
|
],
|
||||||
|
'cdn css' => [
|
||||||
|
AssetsMode::CDN,
|
||||||
|
'style.css',
|
||||||
|
'<link rel="stylesheet" href="'.$cdnDir.'/style.css">',
|
||||||
|
],
|
||||||
|
'offline css' => [
|
||||||
|
AssetsMode::OFFLINE,
|
||||||
|
'style.css',
|
||||||
|
'<style>'.file_get_contents($resourceDir.'/style.css').'</style>',
|
||||||
|
],
|
||||||
|
'external css' => [
|
||||||
|
AssetsMode::BUNDLE,
|
||||||
|
'https://cdn.com/my.css',
|
||||||
|
'<link rel="stylesheet" href="https://cdn.com/my.css">',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function provideJs($cdnDir, $resourceDir)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'bundled js' => [
|
||||||
|
AssetsMode::BUNDLE,
|
||||||
|
'init-swagger-ui.js',
|
||||||
|
'<script src="/bundles/nelmioapidoc/init-swagger-ui.js"></script>',
|
||||||
|
],
|
||||||
|
'cdn js' => [
|
||||||
|
AssetsMode::CDN,
|
||||||
|
'init-swagger-ui.js',
|
||||||
|
'<script src="'.$cdnDir.'/init-swagger-ui.js"></script>',
|
||||||
|
],
|
||||||
|
'offline js' => [
|
||||||
|
AssetsMode::OFFLINE,
|
||||||
|
'init-swagger-ui.js',
|
||||||
|
'<script>'.file_get_contents($resourceDir.'/init-swagger-ui.js').'</script>',
|
||||||
|
],
|
||||||
|
'external js' => [
|
||||||
|
AssetsMode::BUNDLE,
|
||||||
|
'https://cdn.com/my.js',
|
||||||
|
'<script src="https://cdn.com/my.js"></script>',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function provideImage($cdnDir)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'bundled image' => [
|
||||||
|
AssetsMode::BUNDLE,
|
||||||
|
'logo.png',
|
||||||
|
'/bundles/nelmioapidoc/logo.png',
|
||||||
|
],
|
||||||
|
'cdn image' => [
|
||||||
|
AssetsMode::CDN,
|
||||||
|
'logo.png',
|
||||||
|
$cdnDir.'/logo.png',
|
||||||
|
],
|
||||||
|
'offline image fallbacks to cdn' => [
|
||||||
|
AssetsMode::OFFLINE,
|
||||||
|
'logo.png',
|
||||||
|
$cdnDir.'/logo.png',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user