This commit is contained in:
Nicolas Debrigode 2024-01-19 11:31:52 +01:00
parent edcb7d26d0
commit 5716e03d07
26 changed files with 163 additions and 63 deletions

36
.github/workflows/php-stan.yaml vendored Normal file
View File

@ -0,0 +1,36 @@
name: PHPStan
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install PHP with extensions
uses: shivammathur/setup-php@v2
with:
coverage: none
#extensions: intl
php-version: '8.3'
tools: composer
- name: Determine composer cache directory
id: composer-cache
run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies installed with composer
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.directory }}
key: composer-${{ runner.os }}-${{ hashFiles('composer.*') }}
restore-keys: composer-${{ runner.os }}-composer-
- name: Install dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Run phpstan
run: vendor/bin/phpstan analyze --no-progress

View File

@ -1,13 +0,0 @@
<?php
$finder = (new PhpCsFixer\Finder())
->in(__DIR__)
->exclude('var')
;
return (new PhpCsFixer\Config())
->setRules([
'@Symfony' => true,
])
->setFinder($finder)
;

14
.twig_cs.dist.php Normal file
View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
use FriendsOfTwig\Twigcs\Config\Config;
use FriendsOfTwig\Twigcs\Config\ConfigInterface;
use FriendsOfTwig\Twigcs\Finder\TemplateFinder;
$finder = TemplateFinder::create()->in(__DIR__.'/templates');
return Config::create()
->setDisplay(ConfigInterface::DISPLAY_BLOCKING)
->setSeverity('error')
->addFinder($finder);

View File

@ -24,12 +24,16 @@ outdated: ## Vérifier que les dépendances sont à jour
code-check: ## Vérification du code PHP
make phpstan
make analysis
make rector
analysis: ## Analyse de la qualité du code PHP
./vendor/bin/phpinsights analyse src -c config/checkers/phpinsights.php
./vendor/bin/phpinsights analyse src -c phpinsights.php
phpstan: ## Analyse statique du code PHP
./vendor/bin/phpstan analyse -c config/checkers/phpstan.neon
./vendor/bin/phpstan analyse -c phpstan.neon
rector: ## Analyse refactoring du code PHP
./vendor/bin/rector process --dry-run --config=rector.php
# SERVEUR SYMFONY ######################################################################################################

View File

@ -7,6 +7,7 @@
"php": ">=8.3",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-sqlite3": "*",
"doctrine/orm": "^2.17",
"symfony/asset": "7.0.*",
"symfony/console": "7.0.*",
@ -24,13 +25,14 @@
"twig/twig": "^3.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.14",
"friendsoftwig/twigcs": "^6.4",
"nunomaduro/phpinsights": "^2.4",
"phpstan/phpstan": "^1.2",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-doctrine": "^1.0",
"phpstan/phpstan-strict-rules": "^1.1",
"phpstan/phpstan-symfony": "^1.0",
"rector/rector": "^0.19",
"symfony/browser-kit": "*",
"symfony/css-selector": "*",
"symfony/debug-bundle": "*",

View File

@ -1,17 +0,0 @@
includes:
- ../../vendor/phpstan/phpstan-strict-rules/rules.neon
- ../../vendor/phpstan/phpstan-doctrine/extension.neon
- ../../vendor/phpstan/phpstan-symfony/rules.neon
- ../../vendor/phpstan/phpstan-symfony/extension.neon
- ../../vendor/phpstan/phpstan-deprecation-rules/rules.neon
parameters:
level: max
paths:
- ../../src
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false
ignoreErrors:
- '#Only booleans are allowed#'

View File

@ -10,6 +10,7 @@ use NunoMaduro\PhpInsights\Domain\Sniffs\ForbiddenSetterSniff;
use PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\UselessOverridingMethodSniff;
use PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff;
use PHP_CodeSniffer\Standards\Generic\Sniffs\Formatting\SpaceAfterNotSniff;
use PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\UpperCaseConstantNameSniff;
use PHP_CodeSniffer\Standards\PSR1\Sniffs\Files\SideEffectsSniff;
use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer;
use PhpCsFixer\Fixer\ReturnNotation\ReturnAssignmentFixer;
@ -105,6 +106,7 @@ return [
PropertyTypeHintSniff::class,
ParameterTypeHintSniff::class,
ReturnTypeHintSniff::class,
UpperCaseConstantNameSniff::class,
],
'config' => [

17
phpstan.neon Normal file
View File

@ -0,0 +1,17 @@
includes:
- ./vendor/phpstan/phpstan-strict-rules/rules.neon
- ./vendor/phpstan/phpstan-doctrine/extension.neon
- ./vendor/phpstan/phpstan-symfony/rules.neon
- ./vendor/phpstan/phpstan-symfony/extension.neon
- ./vendor/phpstan/phpstan-deprecation-rules/rules.neon
parameters:
level: max
paths:
- ./src
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false
ignoreErrors:
- '#Only booleans are allowed#'

3
public/assets/custom.css Normal file
View File

@ -0,0 +1,3 @@
.rank {
color: #aaa !important;
}

50
rector.php Normal file
View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector;
use Rector\PHPUnit\CodeQuality\Rector\Class_\AddSeeTestAnnotationRector;
use Rector\PHPUnit\CodeQuality\Rector\Class_\PreferPHPUnitThisCallRector;
use Rector\Set\ValueObject\SetList;
use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
use Rector\Symfony\Set\SymfonySetList;
use Rector\Symfony\Set\TwigSetList;
return static function (RectorConfig $rectorConfig): void {
// bootstrap files
$rectorConfig->bootstrapFiles([__DIR__.'/vendor/autoload.php']);
// paths
$rectorConfig->paths([
__DIR__.'/src',
__DIR__.'/public',
]);
// rules to skip
$rectorConfig->skip([
AddSeeTestAnnotationRector::class,
DisallowedEmptyRuleFixerRector::class,
PreferPHPUnitThisCallRector::class,
AddOverrideAttributeToOverriddenMethodsRector::class,
]);
// rules to apply
$rectorConfig->sets([
// global
SetList::PHP_83,
SetList::CODE_QUALITY,
// Doctrine
DoctrineSetList::DOCTRINE_DBAL_30,
DoctrineSetList::DOCTRINE_CODE_QUALITY,
// Symfony
SymfonySetList::SYMFONY_63,
SymfonySetList::SYMFONY_CODE_QUALITY,
SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES,
SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION,
// twig
TwigSetList::TWIG_240,
TwigSetList::TWIG_UNDERSCORE_TO_NAMESPACE,
]);
};

View File

@ -37,11 +37,7 @@ class ConfigApplication
public function isDev(): bool
{
if ('dev' === $this->environment) {
return true;
}
return false;
return 'dev' === $this->environment;
}
public static function getRelease(): mixed

View File

@ -53,7 +53,7 @@ class CreateAsInfoDbCommand extends Command
$this->io->write('Get data ');
$getData = $this->getData($sendCommand);
if (!$getData) {
if ('' === $getData || '0' === $getData) {
$this->io->warning('Unable to get data.');
return Command::FAILURE;
@ -64,7 +64,7 @@ class CreateAsInfoDbCommand extends Command
$this->io->write('Parse data ');
$parsedData = $this->parseData($getData);
if (!$parsedData) {
if ([] === $parsedData) {
$this->io->warning('No data to process.');
return Command::FAILURE;

View File

@ -23,11 +23,11 @@ class BaseController extends AbstractController
$this->base_data['top'] = $Config::getAsStatsConfigTop();
if (\array_key_exists('top', $this->base_data['request'])) {
$this->base_data['request']['top'] = \intval($this->base_data['request']['top']);
$this->base_data['request']['top'] = (int) $this->base_data['request']['top'];
if ($this->base_data['request']['top'] > 200) {
$this->base_data['top'] = 200;
} elseif ($this->base_data['request']['top']) {
$this->base_data['top'] = $this->base_data['request']['top'] = 200;
} elseif (0 !== $this->base_data['request']['top']) {
$this->base_data['top'] = $this->base_data['request']['top'];
}
}

View File

@ -44,7 +44,7 @@ class ConfigErrorListener implements EventSubscriberInterface
'status_code' => 500,
'status_text' => \sprintf('Problem on asstats.yml : %s', $exception->getMessage()),
]),
500,
Response::HTTP_INTERNAL_SERVER_ERROR,
);
$event->setResponse($response);

View File

@ -44,7 +44,7 @@ class DbErrorListener implements EventSubscriberInterface
'status_code' => 500,
'status_text' => $exception->getMessage(),
]),
500,
Response::HTTP_INTERNAL_SERVER_ERROR,
);
$event->setResponse($response);

View File

@ -44,7 +44,7 @@ class FileNotFoundListener implements EventSubscriberInterface
'status_code' => 500,
'status_text' => $exception->getMessage(),
]),
500,
Response::HTTP_INTERNAL_SERVER_ERROR,
);
$event->setResponse($response);

View File

@ -44,7 +44,7 @@ class KnownLinksEmptyListener implements EventSubscriberInterface
'status_code' => 500,
'status_text' => \sprintf('Problem on asstats.yml : %s', $exception->getMessage()),
]),
500,
Response::HTTP_INTERNAL_SERVER_ERROR,
);
$event->setResponse($response);

View File

@ -18,7 +18,7 @@ class CustomLinksRepository
$htmllinks[] = \sprintf('<a href="%s" target="_blank">%s</a>', $url, \htmlspecialchars($linkname));
}
return join(' | ', $htmllinks);
return \implode(' | ', $htmllinks);
} catch (\Exception) {
return '';
}

View File

@ -70,7 +70,7 @@ class DbAsInfoRepository
$io->progressFinish();
if ($count) {
if (0 !== $count) {
$filesystem->remove(\sprintf('%s.bak', $this->dbname));
return true;

View File

@ -34,7 +34,7 @@ class DbAsStatsRepository
*/
public function getASStatsTop(int $ntop, array $selected_links, array $list_asn = []): array
{
if (!$selected_links) {
if ([] === $selected_links) {
$selected_links = [];
foreach (KnowlinksRepository::get() as $link) {
$selected_links[] = $link['tag'];
@ -50,7 +50,7 @@ class DbAsStatsRepository
}
try {
if ($list_asn) {
if ([] !== $list_asn) {
$asn = $this->cnx->createQueryBuilder()
->select(\sprintf('asn, %s %s as total', $query_links, $query_total))
->from('stats')
@ -78,14 +78,14 @@ class DbAsStatsRepository
$tot_v6_out = 0;
foreach ($row as $key => $value) {
if (false !== \str_contains($key, '_in')) {
if (false !== \str_contains($key, '_v6_')) {
if (\str_contains($key, '_in')) {
if (\str_contains($key, '_v6_')) {
$tot_v6_in += $value;
} else {
$tot_in += $value;
}
} elseif (false !== \str_contains($key, '_out')) {
if (false !== \str_contains($key, '_v6_')) {
} elseif (\str_contains($key, '_out')) {
if (\str_contains($key, '_v6_')) {
$tot_v6_out += $value;
} else {
$tot_out += $value;

View File

@ -18,7 +18,7 @@ class GetAsDataRepository
*/
public static function get(int $top, ?string $topInterval = null): array
{
if (!$top) {
if (0 === $top) {
return [];
}

View File

@ -54,7 +54,7 @@ class KnowlinksRepository
}
}
if (!$knownlinks) {
if ([] === $knownlinks) {
throw new KnownLinksEmptyException('File knownlinks file is empty');
}

View File

@ -27,6 +27,9 @@ readonly class MenuAnnotationControllerEventSubscriber implements EventSubscribe
];
}
/**
* @throws \ReflectionException
*/
public function handle(ControllerEvent $event): void
{
$controllers = $event->getController();
@ -43,7 +46,7 @@ readonly class MenuAnnotationControllerEventSubscriber implements EventSubscribe
$methodAttribute = $this->getMethodeAttribute($controller, $methodName);
if (null !== $methodAttribute) {
if ($methodAttribute instanceof Menu) {
$this->registerMenuToTwig($methodAttribute);
return;
@ -51,7 +54,7 @@ readonly class MenuAnnotationControllerEventSubscriber implements EventSubscribe
$classAttribute = $this->getClassAttribute($controller);
if (null !== $classAttribute) {
if ($classAttribute instanceof Menu) {
$this->registerMenuToTwig($classAttribute);
return;

View File

@ -9,6 +9,7 @@
<link rel="stylesheet" href="{{ asset('assets/templates/tabler.min.css') }}">
<link rel="stylesheet" href="{{ asset('assets/tabler-icons/tabler-icons.min.css') }}">
<link rel="stylesheet" href="{{ asset('assets/flags/flags.min.css') }}">
<link rel="stylesheet" href="{{ asset('assets/custom.css') }}">
{% block css %}{% endblock %}
</head>

View File

@ -1,6 +1,6 @@
{% extends "base/_layout.html.twig" %}
{% block title %}dede{% endblock %}
{% block title %}Top {{ base_data.top }} AS ({{ hours|default('24 hours') }}){% endblock %}
{% block css %}
{{ parent() }}
@ -26,6 +26,10 @@
<div class="small">IPv6: ~ {{ as_data.v6.in|format_bytes }} in / {{ as_data.v6.out|format_bytes }} out</div>
{% endif %}
<div class="small">{{ attribute(data.customlinks, as)|raw }}</div>
<div class="display-6 fw-bold my-3 rank">
{% set counter = counter + 1 %}
# {{ counter }}
</div>
</div>
<div class="col">
graph_v4
@ -37,8 +41,6 @@
{% endif %}
</div>
</div>
{% set counter = counter + 1 %}
{% endfor %}
</div>
</div>