feat: add config redis cache, categories cache (#44)

This commit is contained in:
2026-01-05 13:14:54 +03:00
committed by Nikita Kiselev
parent 3a1f8dbf94
commit 0798f5c3e9
12 changed files with 90 additions and 81 deletions

View File

@@ -1,3 +1,8 @@
APP_DEBUG=true
PULSE_API_HOST=https://pulse.telecart.pro/api/
PULSE_HEARTBEAT_SECRET=c5261f5d-529e-45ad-a69c-9778b755b7cb
TELECART_CACHE_DRIVER=redis
#TELECART_REDIS_HOST=redis
#TELECART_REDIS_PORT=6379
#TELECART_REDIS_DATABASE=0

View File

@@ -1,3 +1,7 @@
APP_DEBUG=false
PULSE_API_HOST=http://host.docker.internal:8086/api/
PULSE_HEARTBEAT_SECRET=c5261f5d-529e-45ad-a69c-9778b755b7cb
TELECART_CACHE_DRIVER=database
TELECART_REDIS_HOST=redis
TELECART_REDIS_PORT=6379
TELECART_REDIS_DATABASE=0

View File

@@ -1,3 +1,7 @@
APP_DEBUG=false
PULSE_API_HOST=https://pulse.telecart.pro/api/
PULSE_HEARTBEAT_SECRET=c5261f5d-529e-45ad-a69c-9778b755b7cb
TELECART_CACHE_DRIVER=mysql
TELECART_REDIS_HOST=redis
TELECART_REDIS_PORT=6379
TELECART_REDIS_DATABASE=0

View File

@@ -1,30 +0,0 @@
<?php
namespace Bastion\Tasks;
use DateInterval;
use Openguru\OpenCartFramework\Cache\CacheInterface;
use Openguru\OpenCartFramework\MaintenanceTasks\BaseMaintenanceTask;
use Psr\Log\LoggerInterface;
class CachePruneTask extends BaseMaintenanceTask
{
private CacheInterface $cache;
public function __construct(LoggerInterface $logger, CacheInterface $cache)
{
parent::__construct($logger);
$this->cache = $cache;
}
public function handle(): void
{
$this->cache->prune();
}
public function interval(): ?DateInterval
{
return new DateInterval('P1D');
}
}

View File

@@ -1,11 +1,9 @@
<?php
use Bastion\Tasks\CachePruneTask;
use Bastion\Tasks\CleanUpOldAssetsTask;
return [
'tasks' => [
CleanUpOldAssetsTask::class,
CachePruneTask::class,
],
];

View File

@@ -56,8 +56,7 @@ class Application extends Container implements LoggerAwareInterface
return new Settings($container->getConfigValue());
});
$dotenv = Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();
$this->loadEnvironmentVariables();
$errorHandler = new ErrorHandler(
$this->get(LoggerInterface::class),
@@ -172,4 +171,30 @@ class Application extends Container implements LoggerAwareInterface
{
$this->logger = $logger;
}
/**
* Loads environment variables from .env files.
* First loads internal .env (from phar or module directory),
* then external .env (if exists next to phar/directory) which overrides values.
*/
private function loadEnvironmentVariables(): void
{
if (!defined('BP_PHAR_BASE_PATH') || !defined('BP_REAL_BASE_PATH')) {
$dotenv = Dotenv::createMutable(__DIR__ . '/../');
$dotenv->load();
return;
}
$internalEnvPath = BP_PHAR_BASE_PATH;
if (is_readable($internalEnvPath . '/.env')) {
$dotenv = Dotenv::createImmutable($internalEnvPath);
$dotenv->load();
}
$externalEnvPath = BP_REAL_BASE_PATH;
if (is_readable($externalEnvPath . '/.env')) {
$dotenv = Dotenv::createImmutable($externalEnvPath);
$dotenv->load();
}
}
}

View File

@@ -11,6 +11,4 @@ interface CacheInterface
public function delete(string $key): void;
public function clear(): void;
public function prune(): void;
}

View File

@@ -41,9 +41,4 @@ class SymfonyMySqlCache implements CacheInterface
{
$this->cache->clear();
}
public function prune(): void
{
$this->cache->prune();
}
}

View File

@@ -41,9 +41,4 @@ class SymfonyRedisCache implements CacheInterface
{
$this->cache->clear();
}
public function prune(): void
{
$this->cache->prune();
}
}

View File

@@ -6,6 +6,7 @@ namespace App\Handlers;
use App\Services\SettingsService;
use App\Support\Utils;
use Openguru\OpenCartFramework\Cache\CacheInterface;
use Openguru\OpenCartFramework\Http\Request;
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
use Openguru\OpenCartFramework\QueryBuilder\Builder;
@@ -21,52 +22,66 @@ class CategoriesHandler
private Builder $queryBuilder;
private ImageFactory $image;
private SettingsService $settings;
private CacheInterface $cache;
public function __construct(Builder $queryBuilder, ImageFactory $ocImageTool, SettingsService $settings)
{
public function __construct(
Builder $queryBuilder,
ImageFactory $ocImageTool,
SettingsService $settings,
CacheInterface $cache
) {
$this->queryBuilder = $queryBuilder;
$this->image = $ocImageTool;
$this->settings = $settings;
$this->cache = $cache;
}
public function index(Request $request): JsonResponse
{
$languageId = $this->settings->config()->getApp()->getLanguageId();
$storeId = $this->settings->get('store.oc_store_id', 0);
$cacheKey = 'categories.index';
$perPage = $request->get('perPage', 100);
$categories = $this->cache->get($cacheKey);
$categoriesFlat = $this->queryBuilder->newQuery()
->select([
'categories.category_id' => 'id',
'categories.parent_id' => 'parent_id',
'categories.image' => 'image',
'descriptions.name' => 'name',
'descriptions.description' => 'description',
])
->from(db_table('category'), 'categories')
->join(
db_table('category_description') . ' AS descriptions',
function (JoinClause $join) use ($languageId) {
$join->on('categories.category_id', '=', 'descriptions.category_id')
->where('descriptions.language_id', '=', $languageId);
}
)
->join(
new Table(db_table('category_to_store'), 'category_to_store'),
function (JoinClause $join) use ($storeId) {
$join->on('category_to_store.category_id', '=', 'categories.category_id')
->where('category_to_store.store_id', '=', $storeId);
}
)
->where('categories.status', '=', 1)
->orderBy('parent_id')
->orderBy('sort_order')
->get();
if ($categories === null) {
$languageId = $this->settings->config()->getApp()->getLanguageId();
$storeId = $this->settings->get('store.oc_store_id', 0);
$categories = $this->buildCategoryTree($categoriesFlat);
$perPage = $request->get('perPage', 100);
$categories = array_slice($categories, 0, $perPage);
$categoriesFlat = $this->queryBuilder->newQuery()
->select([
'categories.category_id' => 'id',
'categories.parent_id' => 'parent_id',
'categories.image' => 'image',
'descriptions.name' => 'name',
'descriptions.description' => 'description',
])
->from(db_table('category'), 'categories')
->join(
db_table('category_description') . ' AS descriptions',
function (JoinClause $join) use ($languageId) {
$join->on('categories.category_id', '=', 'descriptions.category_id')
->where('descriptions.language_id', '=', $languageId);
}
)
->join(
new Table(db_table('category_to_store'), 'category_to_store'),
function (JoinClause $join) use ($storeId) {
$join->on('category_to_store.category_id', '=', 'categories.category_id')
->where('category_to_store.store_id', '=', $storeId);
}
)
->where('categories.status', '=', 1)
->orderBy('parent_id')
->orderBy('sort_order')
->get();
$categories = $this->buildCategoryTree($categoriesFlat);
$categories = array_slice($categories, 0, $perPage);
$this->cache->set($cacheKey, $categories, 60 * 60 * 24);
}
return new JsonResponse([
'data' => array_map(static function ($category) {