Линтовка

This commit is contained in:
2026-01-03 01:12:18 +08:00
parent ddc4374dd6
commit aabad9d744
20 changed files with 224 additions and 190 deletions

View File

@@ -725,7 +725,7 @@ $finder = (new Finder())
->notPath($excludeNames); // исключаем файлы
return (new Config())
// спорная фигня, пока не
// спорная фигня, пока не активирую
// ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect());
->setFinder($finder)
->setRules($rules) // ставим правила

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -42,6 +43,7 @@ class ApiController extends BasicController
if ($playlist['isOnline'] === true) {
unset($playlist['content']);
}
return $this->responseJson($response, 200, $playlist);
} catch (PlaylistNotFoundException $e) {
return $this->responseJsonError($response, 404, $e);
@@ -65,7 +67,7 @@ class ApiController extends BasicController
return $response->withStatus(404);
}
$filePath = cache_path("qr-codes/$code.jpg");
$filePath = cache_path("qr-codes/{$code}.jpg");
if (file_exists($filePath)) {
$raw = file_get_contents($filePath);
} else {
@@ -74,13 +76,14 @@ class ApiController extends BasicController
'outputType' => QRCode::OUTPUT_IMAGE_JPG,
'eccLevel' => QRCode::ECC_L,
]);
$data = config('app.mirror_url') ? mirror_url("$code.m3u") : base_url("$code.m3u");
$data = config('app.mirror_url') ? mirror_url("{$code}.m3u") : base_url("{$code}.m3u");
$raw = new QRCode($options)->render($data, $filePath);
$raw = base64_decode(str_replace('data:image/jpg;base64,', '', $raw));
}
$mime = mime_content_type($filePath);
$response->getBody()->write($raw);
return $response->withStatus(200)
->withHeader('Content-Type', $mime);
}
@@ -116,10 +119,11 @@ class ApiController extends BasicController
function getSize(string $directory): int
{
$size = 0;
foreach (glob($directory . '/*') as $path){
foreach (glob($directory . '/*') as $path) {
is_file($path) && $size += filesize($path);
is_dir($path) && $size += getSize($path);
}
return $size;
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -56,6 +57,7 @@ class BasicController
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$response->getBody()->write($json);
return $response->withStatus($status)
->withHeader('Content-Type', 'application/json');
}
@@ -99,6 +101,7 @@ class BasicController
array $data = [],
): ResponseInterface {
$view = Twig::fromRequest($request);
return $view->render($response, $template, $data);
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -42,7 +43,7 @@ class WebController extends BasicController
$pageSize = config('app.page_size');
if ($pageSize > 0) {
$pageCurrent = (int)($request->getAttributes()['page'] ?? $request->getQueryParams()['page'] ?? 1);
$pageCurrent = (int) ($request->getAttributes()['page'] ?? $request->getQueryParams()['page'] ?? 1);
$pageCount = ceil($count / $pageSize);
$offset = max(0, ($pageCurrent - 1) * $pageSize);
$ini = array_slice($ini, $offset, $pageSize, true);
@@ -76,6 +77,7 @@ class WebController extends BasicController
try {
$playlist = ini()->getPlaylist($code);
return $response->withHeader('Location', $playlist['url']);
} catch (Throwable) {
return $this->notFound($request, $response);
@@ -99,6 +101,7 @@ class WebController extends BasicController
try {
$playlist = ini()->getPlaylist($code);
return $this->view($request, $response, 'details.twig', ['playlist' => $playlist]);
} catch (PlaylistNotFoundException) {
return $this->notFound($request, $response);

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -72,6 +73,7 @@ class IniFile
{
empty($this->playlists) && $this->load();
$data = redis()->get($code);
return $this->initPlaylist($code, $data);
}
@@ -96,11 +98,11 @@ class IniFile
protected function initPlaylist(string $code, array|false $data): array
{
if ($data === false) {
$raw = $this->playlists[$code]
$raw = $this->playlists[$code]
?? throw new PlaylistNotFoundException($code);
$data = [
'code' => $code,
'name' => $raw['name'] ?? "Плейлист #$code",
'name' => $raw['name'] ?? "Плейлист #{$code}",
'description' => $raw['desc'] ?? null,
'url' => $raw['pls'],
'source' => $raw['src'] ?? null,
@@ -182,7 +184,7 @@ class IniFile
return array_any(
$badAttributes,
static fn (string $badAttribute) => preg_match_all("/$badAttribute/", $string) >= 1,
static fn (string $badAttribute) => preg_match_all("/{$badAttribute}/", $string) >= 1,
);
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -30,11 +31,6 @@ final class Kernel
*/
public const string VERSION = '1.0.0';
/**
* @var Kernel
*/
private static Kernel $instance;
/**
* @var App
*/
@@ -55,6 +51,11 @@ final class Kernel
*/
protected ?Redis $cache = null;
/**
* @var Kernel
*/
private static Kernel $instance;
/**
* Закрытый конструктор
*
@@ -75,11 +76,73 @@ final class Kernel
*
* @return Kernel
*/
public static function instance(): Kernel
public static function instance(): self
{
return self::$instance ??= new self();
}
/**
* Возвращает объект подключения к Redis
*
* @return Redis
* @see https://github.com/phpredis/phpredis/?tab=readme-ov-file
*/
public function redis(): Redis
{
if (!empty($this->cache)) {
return $this->cache;
}
$options = [
'host' => $this->config['cache']['host'],
'port' => (int) $this->config['cache']['port'],
];
if (!empty($this->config['cache']['password'])) {
$options['auth'] = $this->config['cache']['password'];
}
$this->cache = new Redis($options);
$this->cache->select((int) $this->config['cache']['db']);
$this->cache->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON);
return $this->cache;
}
/**
* Возвращает значение из конфига
*
* @param string $key Ключ в формате "config.key"
* @param mixed|null $default Значение по умолчанию
* @return mixed
*/
public function config(string $key, mixed $default = null): mixed
{
$parts = explode('.', $key);
return $this->config[$parts[0]][$parts[1]] ?? $default;
}
/**
* Возвращает объект приложения
*
* @return App
*/
public function app(): App
{
return $this->app;
}
/**
* Возвращает объект ini-файла
*
* @return IniFile
*/
public function ini(): IniFile
{
return $this->iniFile ??= new IniFile();
}
/**
* Загружает файл .env или .env.$env
*
@@ -88,12 +151,13 @@ final class Kernel
*/
protected function loadDotEnvFile(string $env = ''): array
{
$filename = empty($env) ? '.env' : ".env.$env";
$filename = empty($env) ? '.env' : ".env.{$env}";
if (!file_exists(root_path($filename))) {
return [];
}
$dotenv = Dotenv::createMutable(root_path(), $filename);
return $dotenv->safeLoad();
}
@@ -138,7 +202,7 @@ final class Kernel
default => throw new InvalidArgumentException(sprintf('Неверный HTTP метод %s', $method))
};
$definition = $this->app->$func($route['path'], $route['handler']);
$definition = $this->app->{$func}($route['path'], $route['handler']);
}
if (!empty($route['name'])) {
@@ -163,65 +227,4 @@ final class Kernel
$twig->addExtension(new DebugExtension());
}
}
/**
* Возвращает объект подключения к Redis
*
* @return Redis
* @see https://github.com/phpredis/phpredis/?tab=readme-ov-file
*/
public function redis(): Redis
{
if (!empty($this->cache)) {
return $this->cache;
}
$options = [
'host' => $this->config['cache']['host'],
'port' => (int)$this->config['cache']['port'],
];
if (!empty($this->config['cache']['password'])) {
$options['auth'] = $this->config['cache']['password'];
}
$this->cache = new Redis($options);
$this->cache->select((int)$this->config['cache']['db']);
$this->cache->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON);
return $this->cache;
}
/**
* Возвращает значение из конфига
*
* @param string $key Ключ в формате "config.key"
* @param mixed|null $default Значение по умолчанию
* @return mixed
*/
public function config(string $key, mixed $default = null): mixed
{
$parts = explode('.', $key);
return $this->config[$parts[0]][$parts[1]] ?? $default;
}
/**
* Возвращает объект приложения
*
* @return App
*/
public function app(): App
{
return $this->app;
}
/**
* Возвращает объект ini-файла
*
* @return IniFile
*/
public function ini(): IniFile
{
return $this->iniFile ??= new IniFile();
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -29,7 +30,36 @@ class StatisticsService
$this->channels = $this->getAllChannels();
}
protected function getPlaylistsByField(string $field, int|string|bool|null $value): array
/**
* Обрабатывает команду /stats
*
* @return bool
* @throws Exception
*/
public function get(): array
{
return [
'playlists' => [
'all' => count($this->playlists),
'online' => count($this->getPlaylistsByField('isOnline', true)),
'offline' => count($this->getPlaylistsByField('isOnline', false)),
'unknown' => count($this->getPlaylistsByField('isOnline', null)),
'adult' => count($this->getPlaylistsByTag('adult')),
'hasCatchup' => count($this->getPlaylistsByField('hasCatchup', true)),
'hasTvg' => count($this->getPlaylistsByField('hasTvg', true)),
'groupped' => count($this->getPlaylistsWithGroups()),
'latest' => $this->getLatestPlaylist(),
],
'channels' => [
'all' => $this->getAllChannelsCount(),
'online' => count($this->getChannelsByField('isOnline', true)),
'offline' => count($this->getChannelsByField('isOnline', false)),
'adult' => count($this->getChannelsByTag('adult')),
],
];
}
protected function getPlaylistsByField(string $field, bool|int|string|null $value): array
{
return array_filter(
$this->playlists,
@@ -85,7 +115,7 @@ class StatisticsService
return count($this->channels);
}
protected function getChannelsByField(string $field, int|string|bool|null $value): array
protected function getChannelsByField(string $field, bool|int|string|null $value): array
{
return array_filter(
$this->channels,
@@ -100,33 +130,4 @@ class StatisticsService
static fn (array $channel) => in_array($tag, $channel['tags']),
);
}
/**
* Обрабатывает команду /stats
*
* @return bool
* @throws Exception
*/
public function get(): array
{
return [
'playlists' => [
'all' => count($this->playlists),
'online' => count($this->getPlaylistsByField('isOnline', true)),
'offline' => count($this->getPlaylistsByField('isOnline', false)),
'unknown' => count($this->getPlaylistsByField('isOnline', null)),
'adult' => count($this->getPlaylistsByTag('adult')),
'hasCatchup' => count($this->getPlaylistsByField('hasCatchup', true)),
'hasTvg' => count($this->getPlaylistsByField('hasTvg', true)),
'groupped' => count($this->getPlaylistsWithGroups()),
'latest' => $this->getLatestPlaylist(),
],
'channels' => [
'all' => $this->getAllChannelsCount(),
'online' => count($this->getChannelsByField('isOnline', true)),
'offline' => count($this->getChannelsByField('isOnline', false)),
'adult' => count($this->getChannelsByTag('adult')),
],
];
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -98,7 +99,7 @@ class TwigExtention extends AbstractExtension
*/
public function toDate(?float $timestamp, string $format = 'd.m.Y H:i:s'): string
{
return $timestamp === null ? '' : date($format, (int)$timestamp);
return $timestamp === null ? '' : date($format, (int) $timestamp);
}
public function arrayValues($value, ...$args)

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -9,9 +10,8 @@ declare(strict_types=1);
namespace App\Errors;
use Psr\Http\Message\{
ResponseInterface,
ServerRequestInterface};
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
use Slim\Handlers\ErrorHandler as SlimErrorHandler;
use Throwable;
@@ -21,33 +21,6 @@ use Throwable;
*/
class ErrorHandler extends SlimErrorHandler
{
/**
* Логирует ошибку и отдаёт JSON-ответ с необходимым содержимым
*
* @param ServerRequestInterface $request
* @param Throwable $exception
* @param bool $displayErrorDetails
* @param bool $logErrors
* @param bool $logErrorDetails
* @param LoggerInterface|null $logger
* @return ResponseInterface
*/
public function __invoke(
ServerRequestInterface $request,
Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails,
?LoggerInterface $logger = null
): ResponseInterface {
$payload = $this->payload($exception, $displayErrorDetails);
$response = app()->getResponseFactory()->createResponse();
$response->getBody()->write(json_encode($payload, JSON_UNESCAPED_UNICODE));
return $response;
}
/**
* Возвращает структуру исключения для контекста
*
@@ -63,7 +36,7 @@ class ErrorHandler extends SlimErrorHandler
'class' => $e::class,
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace()
'trace' => $e->getTrace(),
];
return $result;
@@ -94,4 +67,31 @@ class ErrorHandler extends SlimErrorHandler
return $result;
}
/**
* Логирует ошибку и отдаёт JSON-ответ с необходимым содержимым
*
* @param ServerRequestInterface $request
* @param Throwable $exception
* @param bool $displayErrorDetails
* @param bool $logErrors
* @param bool $logErrorDetails
* @param LoggerInterface|null $logger
* @return ResponseInterface
*/
public function __invoke(
ServerRequestInterface $request,
Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails,
?LoggerInterface $logger = null
): ResponseInterface {
$payload = $this->payload($exception, $displayErrorDetails);
$response = app()->getResponseFactory()->createResponse();
$response->getBody()->write(json_encode($payload, JSON_UNESCAPED_UNICODE));
return $response;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -15,6 +16,6 @@ class InvalidTelegramSecretException extends Exception
{
public function __construct()
{
parent::__construct("Ошибка валидации запроса от Telegram Bot API");
parent::__construct('Ошибка валидации запроса от Telegram Bot API');
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -15,6 +16,6 @@ class PlaylistNotFoundException extends Exception
{
public function __construct(string $code)
{
parent::__construct("Плейлист '$code' не найден");
parent::__construct("Плейлист '{$code}' не найден");
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -17,8 +18,8 @@ if (!function_exists('root_path')) {
/**
* Возвращает абсолютный путь к корневой директории приложения.
*
* @param string $path Относительный путь для добавления к корневому.
* @return string Абсолютный путь.
* @param string $path относительный путь для добавления к корневому
* @return string абсолютный путь
*/
function root_path(string $path = ''): string
{
@@ -32,12 +33,12 @@ if (!function_exists('config_path')) {
/**
* Возвращает абсолютный путь к директории конфигурации приложения.
*
* @param string $path Относительный путь для добавления к директории конфигурации.
* @return string Абсолютный путь.
* @param string $path относительный путь для добавления к директории конфигурации
* @return string абсолютный путь
*/
function config_path(string $path = ''): string
{
return root_path("config/$path");
return root_path("config/{$path}");
}
}
@@ -45,12 +46,12 @@ if (!function_exists('cache_path')) {
/**
* Возвращает абсолютный путь к директории кэша приложения.
*
* @param string $path Относительный путь для добавления к директории кэша.
* @return string Абсолютный путь.
* @param string $path относительный путь для добавления к директории кэша
* @return string абсолютный путь
*/
function cache_path(string $path = ''): string
{
return root_path("cache/$path");
return root_path("cache/{$path}");
}
}
@@ -58,8 +59,8 @@ if (!function_exists('base_url')) {
/**
* Возвращает базовый URL приложения.
*
* @param string $route Дополнительный маршрут, который будет добавлен к базовому URL.
* @return string Полный URL.
* @param string $route дополнительный маршрут, который будет добавлен к базовому URL
* @return string полный URL
*/
function base_url(string $route = ''): string
{
@@ -71,7 +72,7 @@ if (!function_exists('kernel')) {
/**
* Возвращает синглтон-экземпляр ядра приложения.
*
* @return Kernel Экземпляр ядра приложения.
* @return Kernel экземпляр ядра приложения
*/
function kernel(): Kernel
{
@@ -83,7 +84,7 @@ if (!function_exists('app')) {
/**
* Возвращает синглтон-экземпляр Slim-приложения.
*
* @return App Экземпляр Slim-приложения.
* @return App экземпляр Slim-приложения
*/
function app(): App
{
@@ -95,9 +96,9 @@ if (!function_exists('config')) {
/**
* Возвращает значение из конфигурации приложения.
*
* @param string $key Ключ конфигурации.
* @param mixed $default Значение по умолчанию, если ключ не найден.
* @return mixed Значение конфигурации или значение по умолчанию.
* @param string $key ключ конфигурации
* @param mixed $default значение по умолчанию, если ключ не найден
* @return mixed значение конфигурации или значение по умолчанию
*/
function config(string $key, mixed $default = null): mixed
{
@@ -109,7 +110,7 @@ if (!function_exists('redis')) {
/**
* Возвращает синглтон-экземпляр Redis-клиента.
*
* @return Redis Экземпляр Redis-клиента.
* @return Redis экземпляр Redis-клиента
*/
function redis(): Redis
{
@@ -121,7 +122,7 @@ if (!function_exists('ini')) {
/**
* Возвращает синглтон-экземпляр IniFile.
*
* @return IniFile Экземпляр IniFile.
* @return IniFile экземпляр IniFile
*/
function ini(): IniFile
{
@@ -273,11 +274,11 @@ if (!function_exists('env')) {
/**
* Возвращает значение переменной окружения.
*
* @param string $key Ключ переменной окружения.
* @param mixed $default Значение по умолчанию, если переменная не найдена.
* @param bool $required Бросать исключение, если переменная обязательна и не найдена.
* @return mixed Значение переменной окружения или значение по умолчанию.
* @throws InvalidArgumentException Если переменная обязательна и не найдена.
* @param string $key ключ переменной окружения
* @param mixed $default значение по умолчанию, если переменная не найдена
* @param bool $required бросать исключение, если переменная обязательна и не найдена
* @return mixed значение переменной окружения или значение по умолчанию
* @throws InvalidArgumentException если переменная обязательна и не найдена
*/
function env(string $key, mixed $default = null, bool $required = false): mixed
{
@@ -311,7 +312,7 @@ if (!function_exists('here')) {
* @param bool $asArray массив или строка в формате `<file|class>:<func>():<line>`
* @return string|array
*/
function here(bool $asArray = false): string|array
function here(bool $asArray = false): array|string
{
$trace = debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS, 2);
@@ -386,7 +387,7 @@ if (!function_exists('as_data_url')) {
*/
function as_data_url(string $data, string $mimeType = 'text/plain'): string
{
return "data://$mimeType,$data";
return "data://{$mimeType},{$data}";
}
}
@@ -473,7 +474,7 @@ if (!function_exists('number_format_local')) {
* @return string Отформатированное число
*/
function number_format_local(
int|float $number,
float|int $number,
int $decimals = 0,
string $decPoint = '.',
string $thousandsSep = ' ',
@@ -494,7 +495,7 @@ if (!function_exists('format_bytes')) {
{
$units = ['Б', 'КБ', 'МБ', 'ГБ', 'ТБ'];
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; ++$i) {
$bytes /= 1024;
}
@@ -581,11 +582,12 @@ if (!function_exists('get_noun_form')) {
if ($lastDigit === 1) {
return $form1;
} elseif ($lastDigit >= 2 && $lastDigit <= 4) {
return $form2;
} else {
return $form5;
}
if ($lastDigit >= 2 && $lastDigit <= 4) {
return $form2;
}
return $form5;
}
}
@@ -605,7 +607,7 @@ if (!function_exists('random_string')) {
$result = '';
$max = strlen($chars) - 1;
for ($i = 0; $i < $length; $i++) {
for ($i = 0; $i < $length; ++$i) {
$result .= $chars[random_int(0, $max)];
}
@@ -702,7 +704,7 @@ if (!function_exists('recast')) {
function recast(string $className, stdClass &$object): mixed
{
if (!class_exists($className)) {
throw new InvalidArgumentException("Class not found: $className");
throw new InvalidArgumentException("Class not found: {$className}");
}
$new = new $className();
@@ -769,7 +771,7 @@ if (!function_exists('mb_count_chars')) {
for ($i = 0; $i < $length; ++$i) {
$char = mb_substr($string, $i, 1, 'UTF-8');
!array_key_exists($char, $unique) && $unique[$char] = 0;
$unique[$char]++;
++$unique[$char];
}
return $unique;
@@ -853,7 +855,7 @@ if (!function_exists('array_last')) {
return $array[$lastKey];
}
for ($i = count($keys) - 1; $i >= 0; $i--) {
for ($i = count($keys) - 1; $i >= 0; --$i) {
$key = $keys[$i];
if ($callback($array[$key], $key)) {
return $array[$key];
@@ -916,7 +918,7 @@ if (!function_exists('array_get')) {
* @param mixed $default Значение по умолчанию
* @return mixed Значение из массива или значение по умолчанию
*/
function array_get(array $array, string|int $key, mixed $default = null): mixed
function array_get(array $array, int|string $key, mixed $default = null): mixed
{
return $array[$key] ?? $default;
}
@@ -1118,7 +1120,7 @@ if (!function_exists('array_recursive_diff')) {
$aReturn[$key] = $aRecursiveDiff;
}
} else {
if ($value != $b[$key]) {
if ($value !== $b[$key]) {
$aReturn[$key] = $value;
}
}
@@ -1400,7 +1402,7 @@ if (!function_exists('flatten')) {
*
* @param array $tree Дерево (например, результат функции tree())
* @param string $branching Ключ ноды, под которым находится массив с дочерними нодами
* @param null|string $leafProperty Ключ ноды, значение коего определяет является ли каждая нода родителем
* @param string|null $leafProperty Ключ ноды, значение коего определяет является ли каждая нода родителем
* @return array Плоский список
*/
function flatten(
@@ -1459,8 +1461,8 @@ if (!function_exists('clear_tree')) {
*
* @param array $node Нода, которая должна быть обработана
* @param string $branching Ключ ноды, под которым находится массив с дочерними нодами
* @param null|string $leafProperty Ключ ноды, значение коего определяет является ли каждая нода родителем
* @return null|array Обработанная нода с хотя бы одним потомком либо null
* @param string|null $leafProperty Ключ ноды, значение коего определяет является ли каждая нода родителем
* @return array|null Обработанная нода с хотя бы одним потомком либо null
*/
function clear_tree(
array $node,

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project

View File

@@ -1,4 +1,6 @@
<?php
declare(strict_types=1);
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
@@ -11,7 +13,6 @@ use App\Controllers\BotController;
use App\Controllers\WebController;
return [
/*
|--------------------------------------------------------------------------
| Web routes
@@ -99,4 +100,3 @@ return [
'name' => 'not-found',
],
];

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project

21
linter
View File

@@ -7,15 +7,12 @@
# shellcheck disable=SC2015
# set -x
# set -o pipefail
########################################################
# Служебные исходные переменные
########################################################
# имя контейнера
CONTAINER="m3u-su-web"
CONTAINER="iptv-web"
# команда для запуска
COMMAND="$1"; shift
@@ -30,7 +27,6 @@ IS_FROM_GIT="$(env | grep -c "GIT_EDITOR=:")"
[[ -f /.dockerenv ]] && IS_FROM_CONTAINER=1 || IS_FROM_CONTAINER=0
# признак режима отладки
[[ $LINTER_DEBUG == 1 ]] && DEBUG_MODE=1
[[ $LINTER_DEBUG -gt 1 ]] && set -x
########################################################
@@ -42,13 +38,11 @@ LINTER_COLORS=${LINTER_COLORS:-$CAN_USE_COLORS}
[[ "$LINTER_COLORS" == 1 ]] && FRESET="$(tput sgr0)" || FRESET=''
[[ "$LINTER_COLORS" == 1 ]] && FBOLD="$(tput bold)" || FBOLD=''
[[ "$LINTER_COLORS" == 1 ]] && FDIM="$(tput dim)" || FDIM=''
[[ "$LINTER_COLORS" == 1 ]] && FBLACK="$(tput setaf 0)" || FBLACK=''
[[ "$LINTER_COLORS" == 1 ]] && FRED="$(tput setaf 1)" || FRED=''
[[ "$LINTER_COLORS" == 1 ]] && FWHITE="$(tput setaf 7)" || FWHITE=''
[[ "$LINTER_COLORS" == 1 ]] && FGREEN="$(tput setaf 2)" || FGREEN=''
[[ "$LINTER_COLORS" == 1 ]] && FBRED="$(tput setab 1)" || FBRED=''
[[ "$LINTER_COLORS" == 1 ]] && FBYELLOW="$(tput setab 3)" || FBYELLOW=''
[[ "$LINTER_COLORS" == 1 ]] && FBLYELLOW="$(tput setab 11)" || FBLYELLOW=''
print() {
echo -e "$*${FRESET}"
@@ -162,6 +156,18 @@ install() {
error "Pre-commit хук НЕ установлен"
}
# Удаляет pre-commit git хук
remove() {
status
[[ -d ./.git/hooks ]] || {
print "Не найден репозиторий '$(pwd)', пропускаю"
exit
}
rm -f ./.git/hooks/pre-commit && \
success "Pre-commit hook удалён" || \
error "Pre-commit хук НЕ удалён"
}
# Запускает проверку код-стайла по всему проекту или только изменённым файлам
style() {
title "[php-cs-fixer] Запущена проверка код-стайла"
@@ -413,6 +419,7 @@ fi
case "$COMMAND" in
h|help ) help "$1" ;;
i|install ) install ;;
r|remove ) remove ;;
s|style ) style "$@" ;;
f|fix ) fix "$@" ;;
p|phpcs ) phpcs "$@" ;;

View File

@@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project