feat: image processing improve
This commit is contained in:
@@ -101,3 +101,4 @@
|
|||||||
- Маркетинговые лозунги и призывы
|
- Маркетинговые лозунги и призывы
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
export function getThumb(imageUrl) {
|
export function getThumb(imageUrl) {
|
||||||
if (!imageUrl) return '/image/no_image.png';
|
const route = 'extension/tgshop/handle';
|
||||||
const extIndex = imageUrl.lastIndexOf('.');
|
const url = new URL(`${window.TeleCart.shop_base_url}/index.php?route=${route}&api_action=getImage&path=${imageUrl}&size=100x100`);
|
||||||
const ext = imageUrl.substring(extIndex);
|
return url.toString();
|
||||||
const filename = imageUrl.substring(0, extIndex);
|
|
||||||
return `/image/cache/${filename}-100x100${ext}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rub(value) {
|
export function rub(value) {
|
||||||
|
|||||||
8
frontend/spa/package-lock.json
generated
8
frontend/spa/package-lock.json
generated
@@ -19,7 +19,7 @@
|
|||||||
"js-md5": "^0.8.3",
|
"js-md5": "^0.8.3",
|
||||||
"ofetch": "^1.4.1",
|
"ofetch": "^1.4.1",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"swiper": "^11.2.10",
|
"swiper": "^12.0.3",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.22",
|
||||||
"vue-imask": "^7.6.1",
|
"vue-imask": "^7.6.1",
|
||||||
"vue-router": "^4.6.3",
|
"vue-router": "^4.6.3",
|
||||||
@@ -5638,9 +5638,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/swiper": {
|
"node_modules/swiper": {
|
||||||
"version": "11.2.10",
|
"version": "12.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz",
|
"resolved": "https://registry.npmjs.org/swiper/-/swiper-12.0.3.tgz",
|
||||||
"integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==",
|
"integrity": "sha512-BHd6U1VPEIksrXlyXjMmRWO0onmdNPaTAFduzqR3pgjvi7KfmUCAm/0cj49u2D7B0zNjMw02TSeXfinC1hDCXg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "patreon",
|
"type": "patreon",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"js-md5": "^0.8.3",
|
"js-md5": "^0.8.3",
|
||||||
"ofetch": "^1.4.1",
|
"ofetch": "^1.4.1",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"swiper": "^11.2.10",
|
"swiper": "^12.0.3",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.22",
|
||||||
"vue-imask": "^7.6.1",
|
"vue-imask": "^7.6.1",
|
||||||
"vue-router": "^4.6.3",
|
"vue-router": "^4.6.3",
|
||||||
|
|||||||
@@ -1,28 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<Swiper
|
<Swiper
|
||||||
:lazy="true"
|
|
||||||
:modules="modules"
|
:modules="modules"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
|
:virtual="virtual"
|
||||||
@sliderMove="hapticScroll"
|
@sliderMove="hapticScroll"
|
||||||
class="radius-box"
|
class="radius-box"
|
||||||
>
|
>
|
||||||
<SwiperSlide
|
<SwiperSlide
|
||||||
v-for="image in images"
|
v-for="(image, index) in images"
|
||||||
:key="image.url"
|
:key="image.url"
|
||||||
|
:virtualIndex="index"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="image.url"
|
:src="image.url"
|
||||||
:alt="image.alt"
|
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
:alt="image.alt"
|
||||||
class="w-full h-full radius-box"
|
class="w-full h-full radius-box"
|
||||||
|
@load="onLoad(image.url)"
|
||||||
|
@error="onLoad(image.url)"
|
||||||
/>
|
/>
|
||||||
|
<div v-if="!loaded[image.url]" class="swiper-lazy-preloader"></div>
|
||||||
</SwiperSlide>
|
</SwiperSlide>
|
||||||
</Swiper>
|
</Swiper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import {ref} from 'vue';
|
||||||
import {Swiper, SwiperSlide} from 'swiper/vue';
|
import {Swiper, SwiperSlide} from 'swiper/vue';
|
||||||
|
import {Pagination, Virtual} from 'swiper/modules';
|
||||||
import {useHapticScroll} from "@/composables/useHapticScroll.js";
|
import {useHapticScroll} from "@/composables/useHapticScroll.js";
|
||||||
|
import 'swiper/css';
|
||||||
|
import 'swiper/css/pagination';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
images: {
|
images: {
|
||||||
@@ -31,12 +39,22 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const modules = [];
|
const modules = [Pagination, Virtual];
|
||||||
const hapticScroll = useHapticScroll();
|
const hapticScroll = useHapticScroll();
|
||||||
const pagination = {
|
const pagination = {
|
||||||
clickable: true,
|
clickable: true,
|
||||||
dynamicBullets: false,
|
dynamicBullets: false,
|
||||||
};
|
};
|
||||||
|
const virtual = {
|
||||||
|
enabled: true,
|
||||||
|
addSlidesAfter: 1,
|
||||||
|
addSlidesBefore: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const loaded = ref({});
|
||||||
|
const onLoad = (url) => {
|
||||||
|
if (url) loaded.value[url] = true;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ use Cart\User;
|
|||||||
use Monolog\Handler\RotatingFileHandler;
|
use Monolog\Handler\RotatingFileHandler;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use Openguru\OpenCartFramework\Application;
|
use Openguru\OpenCartFramework\Application;
|
||||||
use Openguru\OpenCartFramework\Http\Response as HttpResponse;
|
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageTool;
|
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
|
||||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@@ -114,6 +111,7 @@ class ControllerExtensionModuleTgshop extends Controller
|
|||||||
$data['customer_groups'] = $this->getCustomerGroups();
|
$data['customer_groups'] = $this->getCustomerGroups();
|
||||||
$data['themes'] = self::$themes;
|
$data['themes'] = self::$themes;
|
||||||
$data['telecart_module_version'] = module_version();
|
$data['telecart_module_version'] = module_version();
|
||||||
|
$data['shop_base_url'] = HTTPS_CATALOG;
|
||||||
|
|
||||||
$data['action'] = $this->url->link(
|
$data['action'] = $this->url->link(
|
||||||
'extension/module/tgshop',
|
'extension/module/tgshop',
|
||||||
@@ -128,21 +126,9 @@ class ControllerExtensionModuleTgshop extends Controller
|
|||||||
{
|
{
|
||||||
$logger = $this->createLogger();
|
$logger = $this->createLogger();
|
||||||
|
|
||||||
try {
|
$this
|
||||||
$this
|
->createApplication($logger)
|
||||||
->createApplication($logger)
|
->bootAndHandleRequest();
|
||||||
->bootAndHandleRequest();
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$logger->error($e->getMessage(), ['exception' => $e]);
|
|
||||||
http_response_code(HttpResponse::HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
echo json_encode([
|
|
||||||
'error' => $e->getMessage(),
|
|
||||||
'code' => $e->getCode(),
|
|
||||||
'file' => $e->getFile(),
|
|
||||||
'line' => $e->getLine(),
|
|
||||||
], JSON_THROW_ON_ERROR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function validate(): bool
|
protected function validate(): bool
|
||||||
@@ -170,31 +156,6 @@ class ControllerExtensionModuleTgshop extends Controller
|
|||||||
|
|
||||||
$data = array_merge($data, $this->error);
|
$data = array_merge($data, $this->error);
|
||||||
|
|
||||||
$data['breadcrumbs'] = array();
|
|
||||||
|
|
||||||
$data['breadcrumbs'][] = array(
|
|
||||||
'text' => $this->language->get('text_home'),
|
|
||||||
'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true)
|
|
||||||
);
|
|
||||||
|
|
||||||
$data['breadcrumbs'][] = array(
|
|
||||||
'text' => $this->language->get('text_module'),
|
|
||||||
'href' => $this->url->link(
|
|
||||||
'marketplace/extension',
|
|
||||||
'user_token=' . $this->session->data['user_token'] . '&type=module',
|
|
||||||
true
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$data['breadcrumbs'][] = array(
|
|
||||||
'text' => $this->language->get('heading_title'),
|
|
||||||
'href' => $this->url->link(
|
|
||||||
'extension/module/tgshop',
|
|
||||||
'user_token=' . $this->session->data['user_token'],
|
|
||||||
true
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isset($this->session->data['success'])) {
|
if (isset($this->session->data['success'])) {
|
||||||
$data['success'] = $this->session->data['success'];
|
$data['success'] = $this->session->data['success'];
|
||||||
|
|
||||||
@@ -255,6 +216,9 @@ class ControllerExtensionModuleTgshop extends Controller
|
|||||||
'shop_base_url' => HTTPS_CATALOG, // for catalog: HTTPS_SERVER, for admin: HTTPS_CATALOG
|
'shop_base_url' => HTTPS_CATALOG, // for catalog: HTTPS_SERVER, for admin: HTTPS_CATALOG
|
||||||
'language_id' => (int) $this->config->get('config_language_id'),
|
'language_id' => (int) $this->config->get('config_language_id'),
|
||||||
],
|
],
|
||||||
|
'paths' => [
|
||||||
|
'images' => DIR_IMAGE,
|
||||||
|
],
|
||||||
'logs' => [
|
'logs' => [
|
||||||
'path' => DIR_LOGS,
|
'path' => DIR_LOGS,
|
||||||
],
|
],
|
||||||
@@ -281,7 +245,6 @@ class ControllerExtensionModuleTgshop extends Controller
|
|||||||
|
|
||||||
$app = ApplicationFactory::create($items);
|
$app = ApplicationFactory::create($items);
|
||||||
$app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
$app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
||||||
$app->bind(ImageToolInterface::class, fn() => new ImageTool(DIR_IMAGE, HTTPS_SERVER));
|
|
||||||
$app->setLogger($logger);
|
$app->setLogger($logger);
|
||||||
|
|
||||||
return $app;
|
return $app;
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
<script>
|
<script>
|
||||||
window.TeleCart = {
|
window.TeleCart = {
|
||||||
user_token: '{{ user_token }}',
|
user_token: '{{ user_token }}',
|
||||||
mainpage_slider: '{{ mainpage_slider }}',
|
|
||||||
themes: '{{ themes | json_encode }}',
|
themes: '{{ themes | json_encode }}',
|
||||||
order_statuses: '{{ order_statuses | json_encode }}',
|
order_statuses: '{{ order_statuses | json_encode }}',
|
||||||
|
shop_base_url: '{{ shop_base_url }}',
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<div id="app" class="telecart-admin-app">App Loading...</div>
|
<div id="app" class="telecart-admin-app">App Loading...</div>
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ use Cart\Currency;
|
|||||||
use Cart\Tax;
|
use Cart\Tax;
|
||||||
use Monolog\Handler\RotatingFileHandler;
|
use Monolog\Handler\RotatingFileHandler;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageTool;
|
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
|
||||||
use Openguru\OpenCartFramework\OpenCart\Currency as TelecartCurrency;
|
use Openguru\OpenCartFramework\OpenCart\Currency as TelecartCurrency;
|
||||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
@@ -54,6 +52,9 @@ class ControllerExtensionTgshopHandle extends Controller
|
|||||||
'language_id' => (int)$this->config->get('config_language_id'),
|
'language_id' => (int)$this->config->get('config_language_id'),
|
||||||
'oc_timezone' => $this->config->get('config_timezone'),
|
'oc_timezone' => $this->config->get('config_timezone'),
|
||||||
],
|
],
|
||||||
|
'paths' => [
|
||||||
|
'images' => DIR_IMAGE,
|
||||||
|
],
|
||||||
'logs' => [
|
'logs' => [
|
||||||
'path' => DIR_LOGS,
|
'path' => DIR_LOGS,
|
||||||
],
|
],
|
||||||
@@ -86,7 +87,6 @@ class ControllerExtensionTgshopHandle extends Controller
|
|||||||
$app->bind(Url::class, fn() => $this->url);
|
$app->bind(Url::class, fn() => $this->url);
|
||||||
$app->bind(Currency::class, fn() => new TelecartCurrency($this->registry));
|
$app->bind(Currency::class, fn() => new TelecartCurrency($this->registry));
|
||||||
$app->bind(Tax::class, fn() => $this->tax);
|
$app->bind(Tax::class, fn() => $this->tax);
|
||||||
$app->bind(ImageToolInterface::class, fn() => new ImageTool(DIR_IMAGE, HTTPS_SERVER));
|
|
||||||
$app->bind(Cart::class, fn() => $this->cart);
|
$app->bind(Cart::class, fn() => $this->cart);
|
||||||
$app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
$app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
||||||
$app->singleton(Log::class, fn() => $this->log);
|
$app->singleton(Log::class, fn() => $this->log);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\ServiceProviders\AppServiceProvider;
|
|||||||
use App\ServiceProviders\SettingsServiceProvider;
|
use App\ServiceProviders\SettingsServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Application;
|
use Openguru\OpenCartFramework\Application;
|
||||||
use Openguru\OpenCartFramework\Cache\CacheServiceProvider;
|
use Openguru\OpenCartFramework\Cache\CacheServiceProvider;
|
||||||
|
use Openguru\OpenCartFramework\ImageTool\ImageToolServiceProvider;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\QueryBuilderServiceProvider;
|
use Openguru\OpenCartFramework\QueryBuilder\QueryBuilderServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
@@ -33,6 +34,7 @@ class ApplicationFactory
|
|||||||
CacheServiceProvider::class,
|
CacheServiceProvider::class,
|
||||||
TelegramServiceProvider::class,
|
TelegramServiceProvider::class,
|
||||||
TeleCartPulseServiceProvider::class,
|
TeleCartPulseServiceProvider::class,
|
||||||
|
ImageToolServiceProvider::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,22 +3,19 @@
|
|||||||
namespace Bastion\Handlers;
|
namespace Bastion\Handlers;
|
||||||
|
|
||||||
use App\Services\SettingsService;
|
use App\Services\SettingsService;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
|
||||||
class DictionariesHandler
|
class DictionariesHandler
|
||||||
{
|
{
|
||||||
private Builder $queryBuilder;
|
private Builder $queryBuilder;
|
||||||
private ImageToolInterface $ocImageTool;
|
|
||||||
private SettingsService $settings;
|
private SettingsService $settings;
|
||||||
|
|
||||||
public function __construct(Builder $queryBuilder, ImageToolInterface $ocImageTool, SettingsService $settings)
|
public function __construct(Builder $queryBuilder, SettingsService $settings)
|
||||||
{
|
{
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->ocImageTool = $ocImageTool;
|
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use JsonException;
|
|||||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
|
|
||||||
class FormsHandler
|
class FormsHandler
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use Openguru\OpenCartFramework\Cache\CacheInterface;
|
|||||||
use Openguru\OpenCartFramework\Config\Settings;
|
use Openguru\OpenCartFramework\Config\Settings;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
|
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use GuzzleHttp\Exception\GuzzleException;
|
|||||||
use Openguru\OpenCartFramework\Cache\CacheInterface;
|
use Openguru\OpenCartFramework\Cache\CacheInterface;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramClientException;
|
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramClientException;
|
||||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace Openguru\OpenCartFramework\Container;
|
|||||||
|
|
||||||
use Openguru\OpenCartFramework\Events\EventDispatcher;
|
use Openguru\OpenCartFramework\Events\EventDispatcher;
|
||||||
use Openguru\OpenCartFramework\Exceptions\ContainerDependencyResolutionException;
|
use Openguru\OpenCartFramework\Exceptions\ContainerDependencyResolutionException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Phar;
|
use Phar;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
@@ -13,6 +12,7 @@ use ReflectionException;
|
|||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use ReflectionNamedType;
|
use ReflectionNamedType;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
// phpcs:disable PSR1.Files.SideEffects
|
// phpcs:disable PSR1.Files.SideEffects
|
||||||
if (! defined('BP_BASE_PATH')) {
|
if (! defined('BP_BASE_PATH')) {
|
||||||
@@ -118,7 +118,7 @@ class Container implements ContainerInterface
|
|||||||
* @param class-string $abstract
|
* @param class-string $abstract
|
||||||
* @throws ReflectionException
|
* @throws ReflectionException
|
||||||
*/
|
*/
|
||||||
public function call(string $abstract, string $method): JsonResponse
|
public function call(string $abstract, string $method): Response
|
||||||
{
|
{
|
||||||
if (! class_exists($abstract)) {
|
if (! class_exists($abstract)) {
|
||||||
throw new ContainerDependencyResolutionException('Could not resolve the concrete: ' . $abstract);
|
throw new ContainerDependencyResolutionException('Could not resolve the concrete: ' . $abstract);
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ namespace Openguru\OpenCartFramework;
|
|||||||
use ErrorException;
|
use ErrorException;
|
||||||
use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
||||||
use Openguru\OpenCartFramework\Exceptions\ActionNotFoundException;
|
use Openguru\OpenCartFramework\Exceptions\ActionNotFoundException;
|
||||||
|
use Openguru\OpenCartFramework\Exceptions\HttpNotFoundException;
|
||||||
use Openguru\OpenCartFramework\Exceptions\InvalidApiTokenException;
|
use Openguru\OpenCartFramework\Exceptions\InvalidApiTokenException;
|
||||||
use Openguru\OpenCartFramework\Exceptions\NonLoggableExceptionInterface;
|
use Openguru\OpenCartFramework\Exceptions\NonLoggableExceptionInterface;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
@@ -72,6 +73,13 @@ class ErrorHandler
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($exception instanceof HttpNotFoundException) {
|
||||||
|
(new JsonResponse([
|
||||||
|
'message' => $exception->getMessage(),
|
||||||
|
], Response::HTTP_NOT_FOUND))->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ($exception instanceof InvalidApiTokenException) {
|
if ($exception instanceof InvalidApiTokenException) {
|
||||||
(new JsonResponse([
|
(new JsonResponse([
|
||||||
'message' => $exception->getMessage(),
|
'message' => $exception->getMessage(),
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class HttpNotFoundException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Openguru\OpenCartFramework\Http;
|
|
||||||
|
|
||||||
class Response
|
|
||||||
{
|
|
||||||
public const HTTP_CONTINUE = 100;
|
|
||||||
public const HTTP_SWITCHING_PROTOCOLS = 101;
|
|
||||||
public const HTTP_PROCESSING = 102; // RFC2518
|
|
||||||
public const HTTP_EARLY_HINTS = 103; // RFC8297
|
|
||||||
public const HTTP_OK = 200;
|
|
||||||
public const HTTP_CREATED = 201;
|
|
||||||
public const HTTP_ACCEPTED = 202;
|
|
||||||
public const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
|
|
||||||
public const HTTP_NO_CONTENT = 204;
|
|
||||||
public const HTTP_RESET_CONTENT = 205;
|
|
||||||
public const HTTP_PARTIAL_CONTENT = 206;
|
|
||||||
public const HTTP_MULTI_STATUS = 207; // RFC4918
|
|
||||||
public const HTTP_ALREADY_REPORTED = 208; // RFC5842
|
|
||||||
public const HTTP_IM_USED = 226; // RFC3229
|
|
||||||
public const HTTP_MULTIPLE_CHOICES = 300;
|
|
||||||
public const HTTP_MOVED_PERMANENTLY = 301;
|
|
||||||
public const HTTP_FOUND = 302;
|
|
||||||
public const HTTP_SEE_OTHER = 303;
|
|
||||||
public const HTTP_NOT_MODIFIED = 304;
|
|
||||||
public const HTTP_USE_PROXY = 305;
|
|
||||||
public const HTTP_RESERVED = 306;
|
|
||||||
public const HTTP_TEMPORARY_REDIRECT = 307;
|
|
||||||
public const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238
|
|
||||||
public const HTTP_BAD_REQUEST = 400;
|
|
||||||
public const HTTP_UNAUTHORIZED = 401;
|
|
||||||
public const HTTP_PAYMENT_REQUIRED = 402;
|
|
||||||
public const HTTP_FORBIDDEN = 403;
|
|
||||||
public const HTTP_NOT_FOUND = 404;
|
|
||||||
public const HTTP_METHOD_NOT_ALLOWED = 405;
|
|
||||||
public const HTTP_NOT_ACCEPTABLE = 406;
|
|
||||||
public const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
|
|
||||||
public const HTTP_REQUEST_TIMEOUT = 408;
|
|
||||||
public const HTTP_CONFLICT = 409;
|
|
||||||
public const HTTP_GONE = 410;
|
|
||||||
public const HTTP_LENGTH_REQUIRED = 411;
|
|
||||||
public const HTTP_PRECONDITION_FAILED = 412;
|
|
||||||
public const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
|
|
||||||
public const HTTP_REQUEST_URI_TOO_LONG = 414;
|
|
||||||
public const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
|
|
||||||
public const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
|
||||||
public const HTTP_EXPECTATION_FAILED = 417;
|
|
||||||
public const HTTP_I_AM_A_TEAPOT = 418; // RFC2324
|
|
||||||
public const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540
|
|
||||||
public const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
|
|
||||||
public const HTTP_LOCKED = 423; // RFC4918
|
|
||||||
public const HTTP_FAILED_DEPENDENCY = 424; // RFC4918
|
|
||||||
public const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04
|
|
||||||
public const HTTP_UPGRADE_REQUIRED = 426; // RFC2817
|
|
||||||
public const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
|
|
||||||
public const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
|
|
||||||
public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
|
|
||||||
public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; // RFC7725
|
|
||||||
public const HTTP_INTERNAL_SERVER_ERROR = 500;
|
|
||||||
public const HTTP_NOT_IMPLEMENTED = 501;
|
|
||||||
public const HTTP_BAD_GATEWAY = 502;
|
|
||||||
public const HTTP_SERVICE_UNAVAILABLE = 503;
|
|
||||||
public const HTTP_GATEWAY_TIMEOUT = 504;
|
|
||||||
public const HTTP_VERSION_NOT_SUPPORTED = 505;
|
|
||||||
public const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295
|
|
||||||
public const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918
|
|
||||||
public const HTTP_LOOP_DETECTED = 508; // RFC5842
|
|
||||||
public const HTTP_NOT_EXTENDED = 510; // RFC2774
|
|
||||||
public const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\ImageTool;
|
||||||
|
|
||||||
|
use Intervention\Image\Image;
|
||||||
|
use Intervention\Image\ImageManager;
|
||||||
|
use RuntimeException;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class ImageFactory
|
||||||
|
{
|
||||||
|
private ?string $path = null;
|
||||||
|
private string $fullPath;
|
||||||
|
private array $modifications = [];
|
||||||
|
|
||||||
|
private string $imageDir;
|
||||||
|
private string $siteUrl;
|
||||||
|
private ImageManager $manager;
|
||||||
|
|
||||||
|
|
||||||
|
private ?Image $image = null;
|
||||||
|
private array $options = [];
|
||||||
|
|
||||||
|
private static array $defaults = [
|
||||||
|
'format' => 'webp',
|
||||||
|
'quality' => 90,
|
||||||
|
'no_image_path' => 'no_image.png',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static array $modificators = [
|
||||||
|
'resize' => [self::class, 'resizeModification'],
|
||||||
|
'cover' => [self::class, 'coverModification'],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(string $imageDir, string $siteUrl, string $driver, array $options = [])
|
||||||
|
{
|
||||||
|
$this->imageDir = rtrim($imageDir, '/');
|
||||||
|
$this->siteUrl = rtrim($siteUrl, '/');
|
||||||
|
$this->manager = new ImageManager(['driver' => $driver]);
|
||||||
|
$this->options = array_merge(self::$defaults, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ImageNotFoundException
|
||||||
|
*/
|
||||||
|
public function make(?string $path = null): self
|
||||||
|
{
|
||||||
|
$this->path = $path;
|
||||||
|
$this->fullPath = $this->imageDir . '/' . $this->path;
|
||||||
|
|
||||||
|
if (! $this->path || ! file_exists($this->fullPath)) {
|
||||||
|
$this->path = $this->options['no_image_path'];
|
||||||
|
$this->fullPath = $this->imageDir . '/' . $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ensureFileExists($this->fullPath);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resize(?int $width = null, ?int $height = null, $operation = 'resize'): self
|
||||||
|
{
|
||||||
|
$this->modifications['resize'] = [
|
||||||
|
'width' => $width,
|
||||||
|
'height' => $height,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cover(?int $width = null, ?int $height = null): self
|
||||||
|
{
|
||||||
|
$this->modifications['cover'] = [
|
||||||
|
'width' => $width,
|
||||||
|
'height' => $height,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function url(?string $format = null, ?int $quality = null): string
|
||||||
|
{
|
||||||
|
$format = $format ?? $this->options['format'];
|
||||||
|
$quality = $quality ?? $this->options['quality'];
|
||||||
|
|
||||||
|
$newImage = $this->resolveNewImagePath($format);
|
||||||
|
|
||||||
|
if (file_exists($newImage)) {
|
||||||
|
return $this->siteUrl . '/image/' . ltrim($newImage, $this->imageDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->image = $this->manager->make($this->fullPath);
|
||||||
|
|
||||||
|
$this->applyModifications();
|
||||||
|
|
||||||
|
$this->ensureDestinationFolterExists($newImage);
|
||||||
|
|
||||||
|
$this->image->encode($format, $quality)->save($newImage);
|
||||||
|
|
||||||
|
return $this->siteUrl . '/image/' . ltrim($newImage, $this->imageDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function response(?string $format = null, ?int $quality = null): Response
|
||||||
|
{
|
||||||
|
$format = $format ?? $this->options['format'];
|
||||||
|
$quality = $quality ?? $this->options['quality'];
|
||||||
|
|
||||||
|
$newImage = $this->resolveNewImagePath($format);
|
||||||
|
|
||||||
|
if (file_exists($newImage)) {
|
||||||
|
return $this->manager->make($newImage)->response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->image = $this->manager->make($this->fullPath);
|
||||||
|
|
||||||
|
$this->applyModifications();
|
||||||
|
|
||||||
|
$this->ensureDestinationFolterExists($newImage);
|
||||||
|
|
||||||
|
$this->image->encode($format, $quality)->save($newImage);
|
||||||
|
|
||||||
|
return $this->image->response();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRealSize(): array
|
||||||
|
{
|
||||||
|
$this->image = $this->manager->make($this->fullPath);
|
||||||
|
|
||||||
|
return [$this->image->getWidth(), $this->image->getHeight()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ImageNotFoundException
|
||||||
|
*/
|
||||||
|
private function ensureFileExists(string $fullPath): void
|
||||||
|
{
|
||||||
|
if (! file_exists($fullPath)) {
|
||||||
|
throw new ImageNotFoundException($fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveNewImagePath(string $format): string
|
||||||
|
{
|
||||||
|
$filename = $this->path;
|
||||||
|
|
||||||
|
$pathinfo = pathinfo($filename);
|
||||||
|
$filename = $pathinfo['filename'];
|
||||||
|
$basename = $pathinfo['basename'];
|
||||||
|
$imagePath = rtrim($this->path, $basename);
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($this->modifications as $name => $modification) {
|
||||||
|
$filename .= '_' . $name . '_' . $modification['width'] . 'x' . $modification['height'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->modifications) {
|
||||||
|
$filename .= hash('SHA256', json_encode($this->modifications));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->imageDir . '/cache/' . $imagePath . $filename . '.' . $format;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function applyModifications(): void
|
||||||
|
{
|
||||||
|
foreach ($this->modifications as $name => $value) {
|
||||||
|
$method = "{$name}Modification";
|
||||||
|
if (! method_exists($this, $method)) {
|
||||||
|
throw new RuntimeException('Modification method ' . $method . ' does not exist');
|
||||||
|
}
|
||||||
|
$this->{$method}(...array_values($value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resizeModification(?int $width = null, ?int $height = null): void
|
||||||
|
{
|
||||||
|
if ($width || $height) {
|
||||||
|
$this->image->resize($width, $height, static fn($constraint) => $constraint->aspectRatio());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function coverModification(?int $width = null, ?int $height = null): void
|
||||||
|
{
|
||||||
|
if ($width || $height) {
|
||||||
|
$this->image->fit($width, $height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function ensureDestinationFolterExists(string $newImage): void
|
||||||
|
{
|
||||||
|
$path = pathinfo($newImage, PATHINFO_DIRNAME);
|
||||||
|
if (! file_exists($path)) {
|
||||||
|
if (! mkdir($path, 0777, true) && ! is_dir($path)) {
|
||||||
|
throw new RuntimeException(sprintf('Directory "%s" was not created', $path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\ImageTool;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class ImageNotFoundException extends Exception
|
||||||
|
{
|
||||||
|
public function __construct(string $path = "", $code = 500, Throwable $previous = null)
|
||||||
|
{
|
||||||
|
$message = 'Image file not found: ' . $path;
|
||||||
|
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Openguru\OpenCartFramework\ImageTool;
|
|
||||||
|
|
||||||
use Intervention\Image\ImageManager;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
|
|
||||||
class ImageTool implements ImageToolInterface
|
|
||||||
{
|
|
||||||
private string $imageDir;
|
|
||||||
private string $siteUrl;
|
|
||||||
private ImageManager $manager;
|
|
||||||
|
|
||||||
public function __construct(string $imageDir, string $siteUrl = '/')
|
|
||||||
{
|
|
||||||
$this->imageDir = rtrim($imageDir, '/') . '/';
|
|
||||||
$this->siteUrl = $siteUrl;
|
|
||||||
|
|
||||||
$driver = extension_loaded('imagick') ? 'imagick' : 'gd';
|
|
||||||
$this->manager = new ImageManager(['driver' => $driver]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resize(
|
|
||||||
string $path,
|
|
||||||
?int $width = null,
|
|
||||||
?int $height = null,
|
|
||||||
?string $default = null,
|
|
||||||
string $format = 'webp'
|
|
||||||
): ?string {
|
|
||||||
$filename = is_file($this->imageDir . $path) ? $path : $default;
|
|
||||||
|
|
||||||
if (! $width && ! $height) {
|
|
||||||
throw new InvalidArgumentException('Width or height must be set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $filename || ! is_file($this->imageDir . $filename)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$realPath = realpath($this->imageDir . $filename);
|
|
||||||
if (strpos($realPath, realpath($this->imageDir)) !== 0) {
|
|
||||||
return null; // безопасность
|
|
||||||
}
|
|
||||||
|
|
||||||
$extless = substr($filename, 0, strrpos($filename, '.'));
|
|
||||||
$imageNew = 'cache/' . $extless . '-' . $width . 'x' . $height . '.' . $format;
|
|
||||||
|
|
||||||
$fullNewPath = $this->imageDir . $imageNew;
|
|
||||||
$fullOldPath = $this->imageDir . $filename;
|
|
||||||
|
|
||||||
if (! is_file($fullNewPath) || filemtime($fullOldPath) > filemtime($fullNewPath)) {
|
|
||||||
$dirPath = dirname($fullNewPath);
|
|
||||||
if (! is_dir($dirPath)) {
|
|
||||||
mkdir($dirPath, 0777, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$image = $this->manager->make($fullOldPath)
|
|
||||||
->resize($width, $height, function ($constraint) {
|
|
||||||
$constraint->aspectRatio();
|
|
||||||
// $constraint->upsize();
|
|
||||||
})
|
|
||||||
->resizeCanvas($width, $height, 'center', false, null);
|
|
||||||
|
|
||||||
$image->encode($format, 75)->save($fullNewPath, 75, $format);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtrim($this->siteUrl, '/') . '/image/' . str_replace($this->imageDir, '', $fullNewPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUrl(string $path): string
|
|
||||||
{
|
|
||||||
return rtrim($this->siteUrl, '/') . '/image/' . str_replace($this->imageDir, '', $path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRealSize(string $path): array
|
|
||||||
{
|
|
||||||
$fullPath = $this->imageDir . $path;
|
|
||||||
|
|
||||||
if (! is_file($fullPath)) {
|
|
||||||
throw new \RuntimeException('Image file not found: ' . $path);
|
|
||||||
}
|
|
||||||
|
|
||||||
$img = $this->manager->make($fullPath);
|
|
||||||
|
|
||||||
return [$img->getWidth(), $img->getHeight()];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function cover(string $path, int $width, int $height, string $position = 'center'): ?string
|
|
||||||
{
|
|
||||||
$format = 'webp';
|
|
||||||
|
|
||||||
if (! $width && ! $height) {
|
|
||||||
throw new InvalidArgumentException('Width or height must be set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $path || ! is_file($this->imageDir . $path)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$realPath = realpath($this->imageDir . $path);
|
|
||||||
if (strpos($realPath, realpath($this->imageDir)) !== 0) {
|
|
||||||
return null; // безопасность
|
|
||||||
}
|
|
||||||
|
|
||||||
$extless = substr($path, 0, strrpos($path, '.'));
|
|
||||||
$imageNew = 'cache/' . $extless . '-' . $width . 'x' . $height . '.' . $format;
|
|
||||||
|
|
||||||
$fullNewPath = $this->imageDir . $imageNew;
|
|
||||||
$fullOldPath = $this->imageDir . $path;
|
|
||||||
|
|
||||||
if (! is_file($fullNewPath) || filemtime($fullOldPath) > filemtime($fullNewPath)) {
|
|
||||||
$dirPath = dirname($fullNewPath);
|
|
||||||
if (! is_dir($dirPath)) {
|
|
||||||
mkdir($dirPath, 0777, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$image = $this->manager->make($fullOldPath)
|
|
||||||
->fit($width, $height, function ($constraint) {
|
|
||||||
// $constraint->upsize();
|
|
||||||
}, $position);
|
|
||||||
|
|
||||||
$image->encode($format, 75)->save($fullNewPath, 75, $format);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtrim($this->siteUrl, '/') . '/image/' . str_replace($this->imageDir, '', $fullNewPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Openguru\OpenCartFramework\ImageTool;
|
|
||||||
|
|
||||||
interface ImageToolInterface
|
|
||||||
{
|
|
||||||
public function getUrl(string $path): string;
|
|
||||||
public function getRealSize(string $path): array;
|
|
||||||
|
|
||||||
public function resize(
|
|
||||||
string $path,
|
|
||||||
?int $width = null,
|
|
||||||
?int $height = null,
|
|
||||||
?string $default = null,
|
|
||||||
string $format = 'webp'
|
|
||||||
): ?string;
|
|
||||||
|
|
||||||
public function cover(string $path, int $width, int $height, string $position = 'center'): ?string;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Openguru\OpenCartFramework\ImageTool;
|
||||||
|
|
||||||
|
use Openguru\OpenCartFramework\Container\Container;
|
||||||
|
use Openguru\OpenCartFramework\Container\ServiceProvider;
|
||||||
|
|
||||||
|
class ImageToolServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
$this->container->bind(ImageFactory::class, function (Container $container) {
|
||||||
|
$driver = extension_loaded('imagick') ? 'imagick' : 'gd';
|
||||||
|
|
||||||
|
return new ImageFactory(
|
||||||
|
$container->getConfigValue('paths.images'),
|
||||||
|
$container->getConfigValue('app.shop_base_url'),
|
||||||
|
$driver
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ use App\ServiceProviders\AppServiceProvider;
|
|||||||
use App\ServiceProviders\SettingsServiceProvider;
|
use App\ServiceProviders\SettingsServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Application;
|
use Openguru\OpenCartFramework\Application;
|
||||||
use Openguru\OpenCartFramework\Cache\CacheServiceProvider;
|
use Openguru\OpenCartFramework\Cache\CacheServiceProvider;
|
||||||
|
use Openguru\OpenCartFramework\ImageTool\ImageToolServiceProvider;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\QueryBuilderServiceProvider;
|
use Openguru\OpenCartFramework\QueryBuilder\QueryBuilderServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
@@ -32,6 +33,7 @@ class ApplicationFactory
|
|||||||
TelegramServiceProvider::class,
|
TelegramServiceProvider::class,
|
||||||
ValidatorServiceProvider::class,
|
ValidatorServiceProvider::class,
|
||||||
TeleCartPulseServiceProvider::class,
|
TeleCartPulseServiceProvider::class,
|
||||||
|
ImageToolServiceProvider::class,
|
||||||
])
|
])
|
||||||
->withMiddlewares([
|
->withMiddlewares([
|
||||||
TelegramValidateInitDataMiddleware::class,
|
TelegramValidateInitDataMiddleware::class,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace App\Exceptions;
|
|||||||
|
|
||||||
use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramInvalidSignatureException;
|
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramInvalidSignatureException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|||||||
@@ -6,24 +6,25 @@ namespace App\Handlers;
|
|||||||
|
|
||||||
use App\Services\SettingsService;
|
use App\Services\SettingsService;
|
||||||
use App\Support\Utils;
|
use App\Support\Utils;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||||
|
use Openguru\OpenCartFramework\Support\Str;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
|
||||||
class CategoriesHandler
|
class CategoriesHandler
|
||||||
{
|
{
|
||||||
private const THUMB_SIZE = 150;
|
private const THUMB_SIZE = 150;
|
||||||
|
|
||||||
private Builder $queryBuilder;
|
private Builder $queryBuilder;
|
||||||
private ImageToolInterface $ocImageTool;
|
private ImageFactory $image;
|
||||||
private SettingsService $settings;
|
private SettingsService $settings;
|
||||||
|
|
||||||
public function __construct(Builder $queryBuilder, ImageToolInterface $ocImageTool, SettingsService $settings)
|
public function __construct(Builder $queryBuilder, ImageFactory $ocImageTool, SettingsService $settings)
|
||||||
{
|
{
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->ocImageTool = $ocImageTool;
|
$this->image = $ocImageTool;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ class CategoriesHandler
|
|||||||
return [
|
return [
|
||||||
'id' => (int) $category['id'],
|
'id' => (int) $category['id'],
|
||||||
'image' => $category['image'] ?? '',
|
'image' => $category['image'] ?? '',
|
||||||
'name' => Utils::htmlEntityEncode($category['name']),
|
'name' => Str::htmlEntityEncode($category['name']),
|
||||||
'description' => $category['description'],
|
'description' => $category['description'],
|
||||||
'children' => $category['children'],
|
'children' => $category['children'],
|
||||||
];
|
];
|
||||||
@@ -82,12 +83,10 @@ class CategoriesHandler
|
|||||||
$category['children'] = $children;
|
$category['children'] = $children;
|
||||||
}
|
}
|
||||||
|
|
||||||
$image = $this->ocImageTool->resize(
|
$image = $this->image
|
||||||
$category['image'] ?? '',
|
->make($category['image'])
|
||||||
self::THUMB_SIZE,
|
->resize(self::THUMB_SIZE, self::THUMB_SIZE)
|
||||||
self::THUMB_SIZE,
|
->url();
|
||||||
'no_image.png'
|
|
||||||
);
|
|
||||||
|
|
||||||
$branch[] = [
|
$branch[] = [
|
||||||
'id' => (int) $category['id'],
|
'id' => (int) $category['id'],
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use JsonException;
|
|||||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
|
|
||||||
class FormsHandler
|
class FormsHandler
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace App\Handlers;
|
namespace App\Handlers;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class HealthCheckHandler
|
class HealthCheckHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Handlers;
|
||||||
|
|
||||||
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
|
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class ImageHandler
|
||||||
|
{
|
||||||
|
private ImageFactory $image;
|
||||||
|
|
||||||
|
public function __construct(ImageFactory $image)
|
||||||
|
{
|
||||||
|
$this->image = $image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getImage(Request $request): Response
|
||||||
|
{
|
||||||
|
$path = $request->query->get('path');
|
||||||
|
[$width, $height] = $this->parseSize($request->query->get('size'));
|
||||||
|
|
||||||
|
return $this->image
|
||||||
|
->make($path)
|
||||||
|
->resize($width, $height)
|
||||||
|
->response();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseSize(?string $size = null): array
|
||||||
|
{
|
||||||
|
if (! $size) {
|
||||||
|
return [null, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sizes = explode('x', $size);
|
||||||
|
|
||||||
|
return array_map(static fn($value) => is_numeric($value) ? (int) $value : null, $sizes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ use App\Exceptions\OrderValidationFailedException;
|
|||||||
use App\Services\OrderCreateService;
|
use App\Services\OrderCreateService;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class OrderHandler
|
class OrderHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use App\Models\TelegramCustomer;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Openguru\OpenCartFramework\Telegram\Enums\TelegramHeader;
|
use Openguru\OpenCartFramework\Telegram\Enums\TelegramHeader;
|
||||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use Exception;
|
|||||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
|
|||||||
@@ -5,27 +5,27 @@ namespace App\Handlers;
|
|||||||
use App\Services\SettingsService;
|
use App\Services\SettingsService;
|
||||||
use Exception;
|
use Exception;
|
||||||
use GuzzleHttp\Exception\ClientException;
|
use GuzzleHttp\Exception\ClientException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||||
use Openguru\OpenCartFramework\Router\Router;
|
use Openguru\OpenCartFramework\Router\Router;
|
||||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
|
||||||
class SettingsHandler
|
class SettingsHandler
|
||||||
{
|
{
|
||||||
private SettingsService $settings;
|
private SettingsService $settings;
|
||||||
private ImageToolInterface $imageTool;
|
private ImageFactory $image;
|
||||||
private Router $router;
|
private Router $router;
|
||||||
private TelegramService $telegramService;
|
private TelegramService $telegramService;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsService $settings,
|
SettingsService $settings,
|
||||||
ImageToolInterface $imageTool,
|
ImageFactory $image,
|
||||||
Router $router,
|
Router $router,
|
||||||
TelegramService $telegramService
|
TelegramService $telegramService
|
||||||
) {
|
) {
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->imageTool = $imageTool;
|
$this->image = $image;
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
$this->telegramService = $telegramService;
|
$this->telegramService = $telegramService;
|
||||||
}
|
}
|
||||||
@@ -39,11 +39,11 @@ class SettingsHandler
|
|||||||
$icons = [];
|
$icons = [];
|
||||||
|
|
||||||
if ($appIcon) {
|
if ($appIcon) {
|
||||||
$icons['icon192'] = $this->imageTool->resize($appIcon, 192, 192, 'no_image.png', 'png') . '?_v=' . $hash;
|
$icons['icon192'] = $this->image->make($appIcon)->resize(192, 192)->url('png') . '?_v=' . $hash;
|
||||||
$icons['icon180'] = $this->imageTool->resize($appIcon, 180, 180, 'no_image.png', 'png') . '?_v=' . $hash;
|
$icons['icon180'] = $this->image->make($appIcon)->resize(180, 180)->url('png') . '?_v=' . $hash;;
|
||||||
$icons['icon152'] = $this->imageTool->resize($appIcon, 152, 152, 'no_image.png', 'png') . '?_v=' . $hash;
|
$icons['icon152'] = $this->image->make($appIcon)->resize(152, 152)->url('png') . '?_v=' . $hash;;
|
||||||
$icons['icon120'] = $this->imageTool->resize($appIcon, 120, 120, 'no_image.png', 'png') . '?_v=' . $hash;
|
$icons['icon120'] = $this->image->make($appIcon)->resize(120, 120)->url('png') . '?_v=' . $hash;
|
||||||
$appIcon = $this->imageTool->resize($appIcon, null, 64, 'no_image.png', 'png') . '?_v=' . $hash;
|
$appIcon = $this->image->make($appIcon)->resize(null, 64)->url('png') . '?_v=' . $hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JsonResponse([
|
return new JsonResponse([
|
||||||
@@ -83,8 +83,8 @@ class SettingsHandler
|
|||||||
|
|
||||||
$appIcon = $this->settings->config()->getApp()->getAppIcon();
|
$appIcon = $this->settings->config()->getApp()->getAppIcon();
|
||||||
if ($appIcon) {
|
if ($appIcon) {
|
||||||
$icon192 = $this->imageTool->resize($appIcon, 192, 192, 'no_image.png', 'png');
|
$icon192 = $this->image->make($appIcon)->resize(192, 192)->url('png');
|
||||||
$icon512 = $this->imageTool->resize($appIcon, 512, 512, 'no_image.png', 'png');
|
$icon512 = $this->image->make($appIcon)->resize(512, 512)->url('png');
|
||||||
$manifest['icons'] = [
|
$manifest['icons'] = [
|
||||||
[
|
[
|
||||||
'src' => $icon192,
|
'src' => $icon192,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace App\Handlers;
|
|||||||
use App\Services\TelegramCustomerService;
|
use App\Services\TelegramCustomerService;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Openguru\OpenCartFramework\TeleCartPulse\TrackingIdGenerator;
|
use Openguru\OpenCartFramework\TeleCartPulse\TrackingIdGenerator;
|
||||||
use Openguru\OpenCartFramework\Telegram\Enums\TelegramHeader;
|
use Openguru\OpenCartFramework\Telegram\Enums\TelegramHeader;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace App\Handlers;
|
|||||||
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Openguru\OpenCartFramework\Http\Request;
|
use Openguru\OpenCartFramework\Http\Request;
|
||||||
use Openguru\OpenCartFramework\Http\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Openguru\OpenCartFramework\TeleCartPulse\PulseIngestException;
|
use Openguru\OpenCartFramework\TeleCartPulse\PulseIngestException;
|
||||||
use Openguru\OpenCartFramework\TeleCartPulse\TeleCartPulseService;
|
use Openguru\OpenCartFramework\TeleCartPulse\TeleCartPulseService;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use Openguru\OpenCartFramework\Cache\CacheInterface;
|
use Openguru\OpenCartFramework\Cache\CacheInterface;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
@@ -18,23 +17,20 @@ class BlocksService
|
|||||||
'products_carousel' => [self::class, 'processProductsCarousel'],
|
'products_carousel' => [self::class, 'processProductsCarousel'],
|
||||||
];
|
];
|
||||||
|
|
||||||
private LoggerInterface $logger;
|
private ImageFactory $image;
|
||||||
private ImageToolInterface $imageTool;
|
|
||||||
private CacheInterface $cache;
|
private CacheInterface $cache;
|
||||||
private SettingsService $settings;
|
private SettingsService $settings;
|
||||||
private Builder $queryBuilder;
|
private Builder $queryBuilder;
|
||||||
private ProductsService $productsService;
|
private ProductsService $productsService;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
LoggerInterface $logger,
|
ImageFactory $image,
|
||||||
ImageToolInterface $imageTool,
|
|
||||||
CacheInterface $cache,
|
CacheInterface $cache,
|
||||||
SettingsService $settings,
|
SettingsService $settings,
|
||||||
Builder $queryBuilder,
|
Builder $queryBuilder,
|
||||||
ProductsService $productsService
|
ProductsService $productsService
|
||||||
) {
|
) {
|
||||||
$this->logger = $logger;
|
$this->image = $image;
|
||||||
$this->imageTool = $imageTool;
|
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
@@ -68,11 +64,8 @@ class BlocksService
|
|||||||
$slides = $block['data']['slides'];
|
$slides = $block['data']['slides'];
|
||||||
foreach ($slides as $slideIndex => $slide) {
|
foreach ($slides as $slideIndex => $slide) {
|
||||||
if (is_file(DIR_IMAGE . $slide['image'])) {
|
if (is_file(DIR_IMAGE . $slide['image'])) {
|
||||||
$block['data']['slides'][$slideIndex]['image'] = $this->imageTool->cover(
|
$image = $this->image->make($slide['image']);
|
||||||
$slide['image'],
|
$block['data']['slides'][$slideIndex]['image'] = $image->cover(1110, 600)->url();
|
||||||
1110,
|
|
||||||
600
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Support\Utils;
|
|
||||||
use Cart\Currency;
|
use Cart\Currency;
|
||||||
use Cart\Tax;
|
use Cart\Tax;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Openguru\OpenCartFramework\CriteriaBuilder\CriteriaBuilder;
|
use Openguru\OpenCartFramework\CriteriaBuilder\CriteriaBuilder;
|
||||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||||
use Psr\Log\LoggerInterface;
|
use Openguru\OpenCartFramework\ImageTool\ImageNotFoundException;
|
||||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||||
@@ -17,6 +16,8 @@ use Openguru\OpenCartFramework\QueryBuilder\RawExpression;
|
|||||||
use Openguru\OpenCartFramework\QueryBuilder\Table;
|
use Openguru\OpenCartFramework\QueryBuilder\Table;
|
||||||
use Openguru\OpenCartFramework\Support\Arr;
|
use Openguru\OpenCartFramework\Support\Arr;
|
||||||
use Openguru\OpenCartFramework\Support\PaginationHelper;
|
use Openguru\OpenCartFramework\Support\PaginationHelper;
|
||||||
|
use Openguru\OpenCartFramework\Support\Str;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class ProductsService
|
class ProductsService
|
||||||
{
|
{
|
||||||
@@ -24,7 +25,7 @@ class ProductsService
|
|||||||
private Currency $currency;
|
private Currency $currency;
|
||||||
private Tax $tax;
|
private Tax $tax;
|
||||||
private SettingsService $settings;
|
private SettingsService $settings;
|
||||||
private ImageToolInterface $ocImageTool;
|
private ImageFactory $image;
|
||||||
private OcRegistryDecorator $oc;
|
private OcRegistryDecorator $oc;
|
||||||
private LoggerInterface $logger;
|
private LoggerInterface $logger;
|
||||||
private CriteriaBuilder $criteriaBuilder;
|
private CriteriaBuilder $criteriaBuilder;
|
||||||
@@ -34,7 +35,7 @@ class ProductsService
|
|||||||
Currency $currency,
|
Currency $currency,
|
||||||
Tax $tax,
|
Tax $tax,
|
||||||
SettingsService $settings,
|
SettingsService $settings,
|
||||||
ImageToolInterface $ocImageTool,
|
ImageFactory $image,
|
||||||
OcRegistryDecorator $registry,
|
OcRegistryDecorator $registry,
|
||||||
LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
CriteriaBuilder $criteriaBuilder
|
CriteriaBuilder $criteriaBuilder
|
||||||
@@ -43,12 +44,15 @@ class ProductsService
|
|||||||
$this->currency = $currency;
|
$this->currency = $currency;
|
||||||
$this->tax = $tax;
|
$this->tax = $tax;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->ocImageTool = $ocImageTool;
|
$this->image = $image;
|
||||||
$this->oc = $registry;
|
$this->oc = $registry;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->criteriaBuilder = $criteriaBuilder;
|
$this->criteriaBuilder = $criteriaBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ImageNotFoundException
|
||||||
|
*/
|
||||||
public function getProductsResponse(array $params, int $languageId): array
|
public function getProductsResponse(array $params, int $languageId): array
|
||||||
{
|
{
|
||||||
$page = $params['page'];
|
$page = $params['page'];
|
||||||
@@ -141,7 +145,7 @@ class ProductsService
|
|||||||
$productsImagesMap = [];
|
$productsImagesMap = [];
|
||||||
foreach ($productsImages as $item) {
|
foreach ($productsImages as $item) {
|
||||||
$productsImagesMap[$item['product_id']][] = [
|
$productsImagesMap[$item['product_id']][] = [
|
||||||
'url' => $this->ocImageTool->resize($item['image'], $imageWidth, $imageHeight, 'placeholder.png'),
|
'url' => $this->image->make($item['image'])->resize($imageWidth, $imageHeight)->url(),
|
||||||
'alt' => 'Product Image',
|
'alt' => 'Product Image',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -157,16 +161,13 @@ class ProductsService
|
|||||||
'data' => array_map(function ($product) use ($productsImagesMap, $imageWidth, $imageHeight, $currency) {
|
'data' => array_map(function ($product) use ($productsImagesMap, $imageWidth, $imageHeight, $currency) {
|
||||||
$allImages = [];
|
$allImages = [];
|
||||||
|
|
||||||
$image = $this->ocImageTool->resize(
|
$image = $this->image->make($product['product_image'])
|
||||||
$product['product_image'],
|
->resize($imageWidth, $imageHeight)
|
||||||
$imageWidth,
|
->url();
|
||||||
$imageHeight,
|
|
||||||
'placeholder.png'
|
|
||||||
);
|
|
||||||
|
|
||||||
$allImages[] = [
|
$allImages[] = [
|
||||||
'url' => $image,
|
'url' => $image,
|
||||||
'alt' => Utils::htmlEntityEncode($product['product_name']),
|
'alt' => Str::htmlEntityEncode($product['product_name']),
|
||||||
];
|
];
|
||||||
|
|
||||||
$priceNumeric = $this->tax->calculate(
|
$priceNumeric = $this->tax->calculate(
|
||||||
@@ -197,7 +198,7 @@ class ProductsService
|
|||||||
return [
|
return [
|
||||||
'id' => (int) $product['product_id'],
|
'id' => (int) $product['product_id'],
|
||||||
'product_quantity' => (int) $product['product_quantity'],
|
'product_quantity' => (int) $product['product_quantity'],
|
||||||
'name' => Utils::htmlEntityEncode($product['product_name']),
|
'name' => Str::htmlEntityEncode($product['product_name']),
|
||||||
'price' => $price,
|
'price' => $price,
|
||||||
'special' => $special,
|
'special' => $special,
|
||||||
'image' => $image,
|
'image' => $image,
|
||||||
@@ -251,13 +252,13 @@ class ProductsService
|
|||||||
$data['tab_review'] = sprintf($this->oc->language->get('tab_review'), $product_info['reviews']);
|
$data['tab_review'] = sprintf($this->oc->language->get('tab_review'), $product_info['reviews']);
|
||||||
|
|
||||||
$data['product_id'] = $productId;
|
$data['product_id'] = $productId;
|
||||||
$data['name'] = Utils::htmlEntityEncode($product_info['name']);
|
$data['name'] = Str::htmlEntityEncode($product_info['name']);
|
||||||
$data['manufacturer'] = $product_info['manufacturer'];
|
$data['manufacturer'] = $product_info['manufacturer'];
|
||||||
$data['model'] = $product_info['model'];
|
$data['model'] = $product_info['model'];
|
||||||
$data['reward'] = $product_info['reward'];
|
$data['reward'] = $product_info['reward'];
|
||||||
$data['points'] = (int) $product_info['points'];
|
$data['points'] = (int) $product_info['points'];
|
||||||
$data['description'] = Utils::htmlEntityEncode($product_info['description']);
|
$data['description'] = Str::htmlEntityEncode($product_info['description']);
|
||||||
$data['share'] = Utils::htmlEntityEncode(
|
$data['share'] = Str::htmlEntityEncode(
|
||||||
$this->oc->url->link('product/product', 'product_id=' . $productId)
|
$this->oc->url->link('product/product', 'product_id=' . $productId)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -281,23 +282,16 @@ class ProductsService
|
|||||||
$images = [];
|
$images = [];
|
||||||
foreach ($allImages as $imagePath) {
|
foreach ($allImages as $imagePath) {
|
||||||
try {
|
try {
|
||||||
[$width, $height] = $this->ocImageTool->getRealSize($imagePath);
|
[$width, $height] = $this->image->make($imagePath)->getRealSize();
|
||||||
$images[] = [
|
$images[] = [
|
||||||
'thumbnailURL' => $this->ocImageTool->resize(
|
'thumbnailURL' => $this->image
|
||||||
$imagePath,
|
->make($imagePath)
|
||||||
$imageThumbWidth,
|
->resize($imageThumbWidth, $imageThumbHeight)
|
||||||
$imageThumbHeight,
|
->url(),
|
||||||
'placeholder.png'
|
'largeURL' => $this->image->make($imagePath)->resize($imageFullWidth, $imageFullHeight)->url(),
|
||||||
),
|
|
||||||
'largeURL' => $this->ocImageTool->resize(
|
|
||||||
$imagePath,
|
|
||||||
$imageFullWidth,
|
|
||||||
$imageFullHeight,
|
|
||||||
'placeholder.png'
|
|
||||||
),
|
|
||||||
'width' => $width,
|
'width' => $width,
|
||||||
'height' => $height,
|
'height' => $height,
|
||||||
'alt' => Utils::htmlEntityEncode($product_info['name']),
|
'alt' => Str::htmlEntityEncode($product_info['name']),
|
||||||
];
|
];
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Handlers\ETLHandler;
|
|||||||
use App\Handlers\FiltersHandler;
|
use App\Handlers\FiltersHandler;
|
||||||
use App\Handlers\FormsHandler;
|
use App\Handlers\FormsHandler;
|
||||||
use App\Handlers\HealthCheckHandler;
|
use App\Handlers\HealthCheckHandler;
|
||||||
|
use App\Handlers\ImageHandler;
|
||||||
use App\Handlers\OrderHandler;
|
use App\Handlers\OrderHandler;
|
||||||
use App\Handlers\PrivacyPolicyHandler;
|
use App\Handlers\PrivacyPolicyHandler;
|
||||||
use App\Handlers\ProductsHandler;
|
use App\Handlers\ProductsHandler;
|
||||||
@@ -22,6 +23,7 @@ return [
|
|||||||
'filtersForMainPage' => [FiltersHandler::class, 'getFiltersForMainPage'],
|
'filtersForMainPage' => [FiltersHandler::class, 'getFiltersForMainPage'],
|
||||||
'getCart' => [CartHandler::class, 'index'],
|
'getCart' => [CartHandler::class, 'index'],
|
||||||
'getForm' => [FormsHandler::class, 'getForm'],
|
'getForm' => [FormsHandler::class, 'getForm'],
|
||||||
|
'getImage' => [ImageHandler::class, 'getImage'],
|
||||||
'health' => [HealthCheckHandler::class, 'handle'],
|
'health' => [HealthCheckHandler::class, 'handle'],
|
||||||
'ingest' => [TelemetryHandler::class, 'ingest'],
|
'ingest' => [TelemetryHandler::class, 'ingest'],
|
||||||
'heartbeat' => [TelemetryHandler::class, 'heartbeat'],
|
'heartbeat' => [TelemetryHandler::class, 'heartbeat'],
|
||||||
|
|||||||
Reference in New Issue
Block a user