feat: add debug mode for developers. Logs improvements

This commit is contained in:
2025-10-26 11:54:05 +03:00
parent d7666f94ba
commit fbccd50675
20 changed files with 176 additions and 18 deletions

View File

@@ -308,6 +308,7 @@ class ControllerExtensionModuleTgshop extends Controller
{
return [
'module_tgshop_status' => 1,
'module_tgshop_debug' => 0,
'module_tgshop_app_name' => $this->config->get('config_meta_title'),
'module_tgshop_app_icon' => $this->config->get('config_image') ?: $this->model_tool_image->resize(
'no_image.png',
@@ -415,6 +416,15 @@ TEXT,
'options' => static::$themes,
'help' => 'Выберите стиль, который будет использоваться при отображении вашего магазина в Telegram для ночного режима. <a href="https://daisyui.com/docs/themes/#list-of-themes" target="_blank">Посмотреть как выглядят темы</a>',
],
'module_tgshop_debug' => [
'type' => 'select',
'options' => [
0 => 'Выключено',
1 => 'Включено',
],
'help' => 'Режим разработчика. Рекомендуется включать только по необходимости. В остальных случаях, для нормальной работы магазина, должен быть выключен.',
],
],
'telegram' => [
'module_tgshop_mini_app_url' => [
@@ -457,9 +467,9 @@ HTML,
'statistics' => [
'module_tgshop_yandex_metrika' => [
'type' => 'textarea',
'placeholder' => 'Вставьте код счётчика Яндекс Метрики',
'placeholder' => 'Вставьте код счётчика Яндекс Метрики.',
'rows' => 15,
'help' => ''
'help' => 'Для проверки интеграции через кнопку "Проверить" в интерфейсе Яндекс Метрики, необходимо сначала включить "Режим разработчика" на вкладке "Общие".'
],
],

View File

@@ -33,6 +33,7 @@ $_['lbl_module_tgshop_enable_store'] = 'Разрешить покупки';
$_['lbl_module_tgshop_feature_coupons'] = 'Промокоды';
$_['lbl_module_tgshop_feature_vouchers'] = 'Подарочные сертификаты';
$_['lbl_module_tgshop_home_banner_id'] = 'Баннер на главной';
$_['lbl_module_tgshop_debug'] = 'Режим разработчика';
// Entry
$_['entry_status'] = 'Статус';

View File

@@ -7,6 +7,7 @@ use Cart\Currency;
use Cart\Tax;
use Openguru\OpenCartFramework\ImageTool\ImageTool;
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
use Openguru\OpenCartFramework\Logger\LoggerInterface;
use Openguru\OpenCartFramework\Logger\OpenCartLogAdapter;
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
@@ -37,8 +38,11 @@ class ControllerExtensionTgshopHandle extends Controller
{
$this->session->data['language'] = $this->config->get('config_language');
$appDebug = filter_var($this->config->get('module_tgshop_debug'), FILTER_VALIDATE_BOOLEAN);
$app = ApplicationFactory::create([
'app_enabled' => filter_var($this->config->get('module_tgshop_status'), FILTER_VALIDATE_BOOLEAN),
'app_debug' => $appDebug,
'oc_config_tax' => $this->config->get('config_tax'),
'oc_default_currency' => $this->config->get('config_currency'),
// ID группы покупателей, которая будет использоаваться в заказах через Телеграм.
@@ -107,7 +111,13 @@ class ControllerExtensionTgshopHandle extends Controller
$app->singleton(Log::class, fn() => $this->log);
$app
->withLogger(fn() => new OpenCartLogAdapter($this->log, 'TeleCart'))
->withLogger(
fn() => new OpenCartLogAdapter(
$this->log,
'TeleCart',
$appDebug ? LoggerInterface::LEVEL_DEBUG : LoggerInterface::LEVEL_WARNING,
)
)
->bootAndHandleRequest();
}

View File

@@ -92,4 +92,27 @@ final class Request
return $headers[mb_strtolower($name)] ?? null;
}
/**
* @param array|string $key
* @return bool
*/
public function has($key): bool
{
if (is_array($key)) {
foreach ($key as $k) {
if ($this->has($k)) {
return true;
}
}
return false;
}
if (array_key_exists($key, $this->query)) {
return true;
}
return $this->json($key) !== null;
}
}

View File

@@ -81,4 +81,9 @@ class Logger implements LoggerInterface
)
);
}
public function debug(string $message): void
{
$this->log($message, LoggerInterface::LEVEL_DEBUG);
}
}

View File

@@ -6,12 +6,15 @@ use Throwable;
interface LoggerInterface
{
public const LEVEL_DEBUG = 0;
public const LEVEL_INFO = 1;
public const LEVEL_WARNING = 2;
public const LEVEL_ERROR = 3;
public function log($message, $level = self::LEVEL_INFO);
public function debug(string $message): void;
public function info(string $message): void;
public function warning(string $message): void;

View File

@@ -9,15 +9,21 @@ class OpenCartLogAdapter implements LoggerInterface
{
private Log $ocLogger;
private string $namespace;
private int $minLogLevel;
public function __construct(Log $ocLogger, string $namespace)
public function __construct(Log $ocLogger, string $namespace, int $minLogLevel = LoggerInterface::LEVEL_WARNING)
{
$this->ocLogger = $ocLogger;
$this->namespace = $namespace;
$this->minLogLevel = $minLogLevel;
}
public function log($message, $level = self::LEVEL_INFO): void
public function log($message, $level = LoggerInterface::LEVEL_INFO): void
{
if ($level < $this->minLogLevel) {
return;
}
$this->ocLogger->write(
sprintf(
"[%s] [%s] %s\n",
@@ -35,12 +41,12 @@ class OpenCartLogAdapter implements LoggerInterface
public function warning(string $message): void
{
$this->log($message, self::LEVEL_WARNING);
$this->log($message, LoggerInterface::LEVEL_WARNING);
}
public function error(string $message): void
{
$this->log($message, self::LEVEL_ERROR);
$this->log($message, LoggerInterface::LEVEL_ERROR);
}
public function logException(Throwable $exception): void
@@ -59,6 +65,8 @@ class OpenCartLogAdapter implements LoggerInterface
private function getLevelString($level): string
{
switch ($level) {
case LoggerInterface::LEVEL_DEBUG:
return 'DEBUG';
case LoggerInterface::LEVEL_INFO:
return 'INFO';
case LoggerInterface::LEVEL_WARNING:
@@ -69,4 +77,9 @@ class OpenCartLogAdapter implements LoggerInterface
return 'UNKNOWN';
}
}
public function debug(string $message): void
{
$this->log($message, LoggerInterface::LEVEL_DEBUG);
}
}

View File

@@ -2,20 +2,31 @@
namespace Openguru\OpenCartFramework\Telegram;
use Openguru\OpenCartFramework\Config\Settings;
use Openguru\OpenCartFramework\Http\Request;
use Openguru\OpenCartFramework\Logger\LoggerInterface;
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramInvalidSignatureException;
class SignatureValidator
{
private ?string $botToken;
private Settings $settings;
private LoggerInterface $logger;
public function __construct(?string $botToken = null)
public function __construct(Settings $settings, LoggerInterface $logger, ?string $botToken = null)
{
$this->botToken = $botToken;
$this->settings = $settings;
$this->logger = $logger;
}
public function validate(Request $request): void
{
if ($this->settings->get('app_debug')) {
$this->logger->warning('Dev Mode is enabled. Ignoring Signature Validation.');
return;
}
if (! $this->botToken) {
return;
}

View File

@@ -3,7 +3,9 @@
namespace Openguru\OpenCartFramework\Telegram;
use Openguru\OpenCartFramework\Application;
use Openguru\OpenCartFramework\Config\Settings;
use Openguru\OpenCartFramework\Container\ServiceProvider;
use Openguru\OpenCartFramework\Logger\LoggerInterface;
class TelegramServiceProvider extends ServiceProvider
{
@@ -16,6 +18,8 @@ class TelegramServiceProvider extends ServiceProvider
$this->container->singleton(SignatureValidator::class, function (Application $app) {
return new SignatureValidator(
$app->get(Settings::class),
$app->get(LoggerInterface::class),
$app->getConfigValue('telegram.bot_token'),
);
});

View File

@@ -42,6 +42,7 @@ class SettingsHandler
return new JsonResponse([
'app_name' => $this->settings->get('app_name'),
'app_debug' => $this->settings->get('app_debug'),
'app_icon' => $appIcon ?? '',
'app_icon192' => $icons['icon192'] ?? '',
'app_icon180' => $icons['icon180'] ?? '',

View File

@@ -0,0 +1,62 @@
<?php
namespace Tests\Unit;
use Openguru\OpenCartFramework\Http\Request;
use PHPUnit\Framework\TestCase;
class RequestTest extends TestCase
{
public function testHasQueryParam(): void
{
$request = new Request(
['foo' => 'bar'],
[],
[],
[],
[]
);
$this->assertTrue($request->has('foo'));
$this->assertFalse($request->has('xyz'));
}
public function testHasJsonParam(): void
{
$request = new Request(
[],
[],
[],
[],
[],
[],
'{"foo":"bar"}'
);
$this->assertTrue($request->has('foo'));
}
public function testHasAtLeastOne(): void
{
$request = new Request(
['foo' => 'bar'],
[],
[],
[],
[],
[],
'{"xyz":"bar"}'
);
$this->assertTrue($request->has([
'foo',
'xyz',
'some_other'
]));
$this->assertFalse($request->has([
'abc',
'some_other'
]));
}
}