feat: image processing improve
This commit is contained in:
@@ -101,3 +101,4 @@
|
||||
- Маркетинговые лозунги и призывы
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
export function getThumb(imageUrl) {
|
||||
if (!imageUrl) return '/image/no_image.png';
|
||||
const extIndex = imageUrl.lastIndexOf('.');
|
||||
const ext = imageUrl.substring(extIndex);
|
||||
const filename = imageUrl.substring(0, extIndex);
|
||||
return `/image/cache/${filename}-100x100${ext}`;
|
||||
const route = 'extension/tgshop/handle';
|
||||
const url = new URL(`${window.TeleCart.shop_base_url}/index.php?route=${route}&api_action=getImage&path=${imageUrl}&size=100x100`);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
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",
|
||||
"ofetch": "^1.4.1",
|
||||
"pinia": "^3.0.3",
|
||||
"swiper": "^11.2.10",
|
||||
"swiper": "^12.0.3",
|
||||
"vue": "^3.5.22",
|
||||
"vue-imask": "^7.6.1",
|
||||
"vue-router": "^4.6.3",
|
||||
@@ -5638,9 +5638,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/swiper": {
|
||||
"version": "11.2.10",
|
||||
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz",
|
||||
"integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==",
|
||||
"version": "12.0.3",
|
||||
"resolved": "https://registry.npmjs.org/swiper/-/swiper-12.0.3.tgz",
|
||||
"integrity": "sha512-BHd6U1VPEIksrXlyXjMmRWO0onmdNPaTAFduzqR3pgjvi7KfmUCAm/0cj49u2D7B0zNjMw02TSeXfinC1hDCXg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "patreon",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"js-md5": "^0.8.3",
|
||||
"ofetch": "^1.4.1",
|
||||
"pinia": "^3.0.3",
|
||||
"swiper": "^11.2.10",
|
||||
"swiper": "^12.0.3",
|
||||
"vue": "^3.5.22",
|
||||
"vue-imask": "^7.6.1",
|
||||
"vue-router": "^4.6.3",
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
<template>
|
||||
<Swiper
|
||||
:lazy="true"
|
||||
:modules="modules"
|
||||
:pagination="pagination"
|
||||
:virtual="virtual"
|
||||
@sliderMove="hapticScroll"
|
||||
class="radius-box"
|
||||
>
|
||||
<SwiperSlide
|
||||
v-for="image in images"
|
||||
v-for="(image, index) in images"
|
||||
:key="image.url"
|
||||
:virtualIndex="index"
|
||||
>
|
||||
<img
|
||||
:src="image.url"
|
||||
:alt="image.alt"
|
||||
loading="lazy"
|
||||
:alt="image.alt"
|
||||
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>
|
||||
</Swiper>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from 'vue';
|
||||
import {Swiper, SwiperSlide} from 'swiper/vue';
|
||||
import {Pagination, Virtual} from 'swiper/modules';
|
||||
import {useHapticScroll} from "@/composables/useHapticScroll.js";
|
||||
import 'swiper/css';
|
||||
import 'swiper/css/pagination';
|
||||
|
||||
const props = defineProps({
|
||||
images: {
|
||||
@@ -31,12 +39,22 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const modules = [];
|
||||
const modules = [Pagination, Virtual];
|
||||
const hapticScroll = useHapticScroll();
|
||||
const pagination = {
|
||||
clickable: true,
|
||||
dynamicBullets: false,
|
||||
};
|
||||
const virtual = {
|
||||
enabled: true,
|
||||
addSlidesAfter: 1,
|
||||
addSlidesBefore: 0,
|
||||
};
|
||||
|
||||
const loaded = ref({});
|
||||
const onLoad = (url) => {
|
||||
if (url) loaded.value[url] = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -5,9 +5,6 @@ use Cart\User;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Logger;
|
||||
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\Support\Arr;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -114,6 +111,7 @@ class ControllerExtensionModuleTgshop extends Controller
|
||||
$data['customer_groups'] = $this->getCustomerGroups();
|
||||
$data['themes'] = self::$themes;
|
||||
$data['telecart_module_version'] = module_version();
|
||||
$data['shop_base_url'] = HTTPS_CATALOG;
|
||||
|
||||
$data['action'] = $this->url->link(
|
||||
'extension/module/tgshop',
|
||||
@@ -128,21 +126,9 @@ class ControllerExtensionModuleTgshop extends Controller
|
||||
{
|
||||
$logger = $this->createLogger();
|
||||
|
||||
try {
|
||||
$this
|
||||
->createApplication($logger)
|
||||
->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);
|
||||
}
|
||||
$this
|
||||
->createApplication($logger)
|
||||
->bootAndHandleRequest();
|
||||
}
|
||||
|
||||
protected function validate(): bool
|
||||
@@ -170,31 +156,6 @@ class ControllerExtensionModuleTgshop extends Controller
|
||||
|
||||
$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'])) {
|
||||
$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
|
||||
'language_id' => (int) $this->config->get('config_language_id'),
|
||||
],
|
||||
'paths' => [
|
||||
'images' => DIR_IMAGE,
|
||||
],
|
||||
'logs' => [
|
||||
'path' => DIR_LOGS,
|
||||
],
|
||||
@@ -281,7 +245,6 @@ class ControllerExtensionModuleTgshop extends Controller
|
||||
|
||||
$app = ApplicationFactory::create($items);
|
||||
$app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
||||
$app->bind(ImageToolInterface::class, fn() => new ImageTool(DIR_IMAGE, HTTPS_SERVER));
|
||||
$app->setLogger($logger);
|
||||
|
||||
return $app;
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
<script>
|
||||
window.TeleCart = {
|
||||
user_token: '{{ user_token }}',
|
||||
mainpage_slider: '{{ mainpage_slider }}',
|
||||
themes: '{{ themes | json_encode }}',
|
||||
order_statuses: '{{ order_statuses | json_encode }}',
|
||||
shop_base_url: '{{ shop_base_url }}',
|
||||
};
|
||||
</script>
|
||||
<div id="app" class="telecart-admin-app">App Loading...</div>
|
||||
|
||||
@@ -7,8 +7,6 @@ use Cart\Currency;
|
||||
use Cart\Tax;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Logger;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageTool;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Openguru\OpenCartFramework\OpenCart\Currency as TelecartCurrency;
|
||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
@@ -54,6 +52,9 @@ class ControllerExtensionTgshopHandle extends Controller
|
||||
'language_id' => (int)$this->config->get('config_language_id'),
|
||||
'oc_timezone' => $this->config->get('config_timezone'),
|
||||
],
|
||||
'paths' => [
|
||||
'images' => DIR_IMAGE,
|
||||
],
|
||||
'logs' => [
|
||||
'path' => DIR_LOGS,
|
||||
],
|
||||
@@ -86,7 +87,6 @@ class ControllerExtensionTgshopHandle extends Controller
|
||||
$app->bind(Url::class, fn() => $this->url);
|
||||
$app->bind(Currency::class, fn() => new TelecartCurrency($this->registry));
|
||||
$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(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
||||
$app->singleton(Log::class, fn() => $this->log);
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\ServiceProviders\AppServiceProvider;
|
||||
use App\ServiceProviders\SettingsServiceProvider;
|
||||
use Openguru\OpenCartFramework\Application;
|
||||
use Openguru\OpenCartFramework\Cache\CacheServiceProvider;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolServiceProvider;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\QueryBuilderServiceProvider;
|
||||
use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
@@ -33,6 +34,7 @@ class ApplicationFactory
|
||||
CacheServiceProvider::class,
|
||||
TelegramServiceProvider::class,
|
||||
TeleCartPulseServiceProvider::class,
|
||||
ImageToolServiceProvider::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,19 @@
|
||||
namespace Bastion\Handlers;
|
||||
|
||||
use App\Services\SettingsService;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
class DictionariesHandler
|
||||
{
|
||||
private Builder $queryBuilder;
|
||||
private ImageToolInterface $ocImageTool;
|
||||
private SettingsService $settings;
|
||||
|
||||
public function __construct(Builder $queryBuilder, ImageToolInterface $ocImageTool, SettingsService $settings)
|
||||
public function __construct(Builder $queryBuilder, SettingsService $settings)
|
||||
{
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
$this->ocImageTool = $ocImageTool;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use JsonException;
|
||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
|
||||
class FormsHandler
|
||||
|
||||
@@ -10,7 +10,7 @@ use Openguru\OpenCartFramework\Cache\CacheInterface;
|
||||
use Openguru\OpenCartFramework\Config\Settings;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
|
||||
@@ -9,7 +9,7 @@ use GuzzleHttp\Exception\GuzzleException;
|
||||
use Openguru\OpenCartFramework\Cache\CacheInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramClientException;
|
||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Openguru\OpenCartFramework\Container;
|
||||
|
||||
use Openguru\OpenCartFramework\Events\EventDispatcher;
|
||||
use Openguru\OpenCartFramework\Exceptions\ContainerDependencyResolutionException;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
use Phar;
|
||||
use Psr\Container\ContainerInterface;
|
||||
@@ -13,6 +12,7 @@ use ReflectionException;
|
||||
use ReflectionMethod;
|
||||
use ReflectionNamedType;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
if (! defined('BP_BASE_PATH')) {
|
||||
@@ -118,7 +118,7 @@ class Container implements ContainerInterface
|
||||
* @param class-string $abstract
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function call(string $abstract, string $method): JsonResponse
|
||||
public function call(string $abstract, string $method): Response
|
||||
{
|
||||
if (! class_exists($abstract)) {
|
||||
throw new ContainerDependencyResolutionException('Could not resolve the concrete: ' . $abstract);
|
||||
|
||||
@@ -5,10 +5,11 @@ namespace Openguru\OpenCartFramework;
|
||||
use ErrorException;
|
||||
use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
||||
use Openguru\OpenCartFramework\Exceptions\ActionNotFoundException;
|
||||
use Openguru\OpenCartFramework\Exceptions\HttpNotFoundException;
|
||||
use Openguru\OpenCartFramework\Exceptions\InvalidApiTokenException;
|
||||
use Openguru\OpenCartFramework\Exceptions\NonLoggableExceptionInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
@@ -72,6 +73,13 @@ class ErrorHandler
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ($exception instanceof HttpNotFoundException) {
|
||||
(new JsonResponse([
|
||||
'message' => $exception->getMessage(),
|
||||
], Response::HTTP_NOT_FOUND))->send();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($exception instanceof InvalidApiTokenException) {
|
||||
(new JsonResponse([
|
||||
'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 Openguru\OpenCartFramework\Application;
|
||||
use Openguru\OpenCartFramework\Cache\CacheServiceProvider;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolServiceProvider;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\QueryBuilderServiceProvider;
|
||||
use Openguru\OpenCartFramework\Router\RouteServiceProvider;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
@@ -32,6 +33,7 @@ class ApplicationFactory
|
||||
TelegramServiceProvider::class,
|
||||
ValidatorServiceProvider::class,
|
||||
TeleCartPulseServiceProvider::class,
|
||||
ImageToolServiceProvider::class,
|
||||
])
|
||||
->withMiddlewares([
|
||||
TelegramValidateInitDataMiddleware::class,
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use Openguru\OpenCartFramework\Contracts\ExceptionHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\Telegram\Exceptions\TelegramInvalidSignatureException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
@@ -6,24 +6,25 @@ namespace App\Handlers;
|
||||
|
||||
use App\Services\SettingsService;
|
||||
use App\Support\Utils;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||
use Openguru\OpenCartFramework\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
class CategoriesHandler
|
||||
{
|
||||
private const THUMB_SIZE = 150;
|
||||
|
||||
private Builder $queryBuilder;
|
||||
private ImageToolInterface $ocImageTool;
|
||||
private ImageFactory $image;
|
||||
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->ocImageTool = $ocImageTool;
|
||||
$this->image = $ocImageTool;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ class CategoriesHandler
|
||||
return [
|
||||
'id' => (int) $category['id'],
|
||||
'image' => $category['image'] ?? '',
|
||||
'name' => Utils::htmlEntityEncode($category['name']),
|
||||
'name' => Str::htmlEntityEncode($category['name']),
|
||||
'description' => $category['description'],
|
||||
'children' => $category['children'],
|
||||
];
|
||||
@@ -82,12 +83,10 @@ class CategoriesHandler
|
||||
$category['children'] = $children;
|
||||
}
|
||||
|
||||
$image = $this->ocImageTool->resize(
|
||||
$category['image'] ?? '',
|
||||
self::THUMB_SIZE,
|
||||
self::THUMB_SIZE,
|
||||
'no_image.png'
|
||||
);
|
||||
$image = $this->image
|
||||
->make($category['image'])
|
||||
->resize(self::THUMB_SIZE, self::THUMB_SIZE)
|
||||
->url();
|
||||
|
||||
$branch[] = [
|
||||
'id' => (int) $category['id'],
|
||||
|
||||
@@ -6,7 +6,7 @@ use JsonException;
|
||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
|
||||
class FormsHandler
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Handlers;
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
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 Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class OrderHandler
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ use App\Models\TelegramCustomer;
|
||||
use Carbon\Carbon;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
use Openguru\OpenCartFramework\Telegram\Enums\TelegramHeader;
|
||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||
|
||||
@@ -10,7 +10,7 @@ use Exception;
|
||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
|
||||
@@ -5,27 +5,27 @@ namespace App\Handlers;
|
||||
use App\Services\SettingsService;
|
||||
use Exception;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||
use Openguru\OpenCartFramework\Router\Router;
|
||||
use Openguru\OpenCartFramework\Telegram\TelegramService;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
class SettingsHandler
|
||||
{
|
||||
private SettingsService $settings;
|
||||
private ImageToolInterface $imageTool;
|
||||
private ImageFactory $image;
|
||||
private Router $router;
|
||||
private TelegramService $telegramService;
|
||||
|
||||
public function __construct(
|
||||
SettingsService $settings,
|
||||
ImageToolInterface $imageTool,
|
||||
ImageFactory $image,
|
||||
Router $router,
|
||||
TelegramService $telegramService
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->imageTool = $imageTool;
|
||||
$this->image = $image;
|
||||
$this->router = $router;
|
||||
$this->telegramService = $telegramService;
|
||||
}
|
||||
@@ -39,11 +39,11 @@ class SettingsHandler
|
||||
$icons = [];
|
||||
|
||||
if ($appIcon) {
|
||||
$icons['icon192'] = $this->imageTool->resize($appIcon, 192, 192, 'no_image.png', 'png') . '?_v=' . $hash;
|
||||
$icons['icon180'] = $this->imageTool->resize($appIcon, 180, 180, 'no_image.png', 'png') . '?_v=' . $hash;
|
||||
$icons['icon152'] = $this->imageTool->resize($appIcon, 152, 152, 'no_image.png', 'png') . '?_v=' . $hash;
|
||||
$icons['icon120'] = $this->imageTool->resize($appIcon, 120, 120, 'no_image.png', 'png') . '?_v=' . $hash;
|
||||
$appIcon = $this->imageTool->resize($appIcon, null, 64, 'no_image.png', 'png') . '?_v=' . $hash;
|
||||
$icons['icon192'] = $this->image->make($appIcon)->resize(192, 192)->url('png') . '?_v=' . $hash;
|
||||
$icons['icon180'] = $this->image->make($appIcon)->resize(180, 180)->url('png') . '?_v=' . $hash;;
|
||||
$icons['icon152'] = $this->image->make($appIcon)->resize(152, 152)->url('png') . '?_v=' . $hash;;
|
||||
$icons['icon120'] = $this->image->make($appIcon)->resize(120, 120)->url('png') . '?_v=' . $hash;
|
||||
$appIcon = $this->image->make($appIcon)->resize(null, 64)->url('png') . '?_v=' . $hash;
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
@@ -83,8 +83,8 @@ class SettingsHandler
|
||||
|
||||
$appIcon = $this->settings->config()->getApp()->getAppIcon();
|
||||
if ($appIcon) {
|
||||
$icon192 = $this->imageTool->resize($appIcon, 192, 192, 'no_image.png', 'png');
|
||||
$icon512 = $this->imageTool->resize($appIcon, 512, 512, 'no_image.png', 'png');
|
||||
$icon192 = $this->image->make($appIcon)->resize(192, 192)->url('png');
|
||||
$icon512 = $this->image->make($appIcon)->resize(512, 512)->url('png');
|
||||
$manifest['icons'] = [
|
||||
[
|
||||
'src' => $icon192,
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace App\Handlers;
|
||||
use App\Services\TelegramCustomerService;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
use Openguru\OpenCartFramework\TeleCartPulse\TrackingIdGenerator;
|
||||
use Openguru\OpenCartFramework\Telegram\Enums\TelegramHeader;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace App\Handlers;
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Openguru\OpenCartFramework\TeleCartPulse\PulseIngestException;
|
||||
use Openguru\OpenCartFramework\TeleCartPulse\TeleCartPulseService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
namespace App\Services;
|
||||
|
||||
use Openguru\OpenCartFramework\Cache\CacheInterface;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||
use RuntimeException;
|
||||
@@ -18,23 +17,20 @@ class BlocksService
|
||||
'products_carousel' => [self::class, 'processProductsCarousel'],
|
||||
];
|
||||
|
||||
private LoggerInterface $logger;
|
||||
private ImageToolInterface $imageTool;
|
||||
private ImageFactory $image;
|
||||
private CacheInterface $cache;
|
||||
private SettingsService $settings;
|
||||
private Builder $queryBuilder;
|
||||
private ProductsService $productsService;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
ImageToolInterface $imageTool,
|
||||
ImageFactory $image,
|
||||
CacheInterface $cache,
|
||||
SettingsService $settings,
|
||||
Builder $queryBuilder,
|
||||
ProductsService $productsService
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->imageTool = $imageTool;
|
||||
$this->image = $image;
|
||||
$this->cache = $cache;
|
||||
$this->settings = $settings;
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
@@ -68,11 +64,8 @@ class BlocksService
|
||||
$slides = $block['data']['slides'];
|
||||
foreach ($slides as $slideIndex => $slide) {
|
||||
if (is_file(DIR_IMAGE . $slide['image'])) {
|
||||
$block['data']['slides'][$slideIndex]['image'] = $this->imageTool->cover(
|
||||
$slide['image'],
|
||||
1110,
|
||||
600
|
||||
);
|
||||
$image = $this->image->make($slide['image']);
|
||||
$block['data']['slides'][$slideIndex]['image'] = $image->cover(1110, 600)->url();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Support\Utils;
|
||||
use Cart\Currency;
|
||||
use Cart\Tax;
|
||||
use Exception;
|
||||
use Openguru\OpenCartFramework\CriteriaBuilder\CriteriaBuilder;
|
||||
use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageFactory;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageNotFoundException;
|
||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||
@@ -17,6 +16,8 @@ use Openguru\OpenCartFramework\QueryBuilder\RawExpression;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Table;
|
||||
use Openguru\OpenCartFramework\Support\Arr;
|
||||
use Openguru\OpenCartFramework\Support\PaginationHelper;
|
||||
use Openguru\OpenCartFramework\Support\Str;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ProductsService
|
||||
{
|
||||
@@ -24,7 +25,7 @@ class ProductsService
|
||||
private Currency $currency;
|
||||
private Tax $tax;
|
||||
private SettingsService $settings;
|
||||
private ImageToolInterface $ocImageTool;
|
||||
private ImageFactory $image;
|
||||
private OcRegistryDecorator $oc;
|
||||
private LoggerInterface $logger;
|
||||
private CriteriaBuilder $criteriaBuilder;
|
||||
@@ -34,7 +35,7 @@ class ProductsService
|
||||
Currency $currency,
|
||||
Tax $tax,
|
||||
SettingsService $settings,
|
||||
ImageToolInterface $ocImageTool,
|
||||
ImageFactory $image,
|
||||
OcRegistryDecorator $registry,
|
||||
LoggerInterface $logger,
|
||||
CriteriaBuilder $criteriaBuilder
|
||||
@@ -43,12 +44,15 @@ class ProductsService
|
||||
$this->currency = $currency;
|
||||
$this->tax = $tax;
|
||||
$this->settings = $settings;
|
||||
$this->ocImageTool = $ocImageTool;
|
||||
$this->image = $image;
|
||||
$this->oc = $registry;
|
||||
$this->logger = $logger;
|
||||
$this->criteriaBuilder = $criteriaBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ImageNotFoundException
|
||||
*/
|
||||
public function getProductsResponse(array $params, int $languageId): array
|
||||
{
|
||||
$page = $params['page'];
|
||||
@@ -141,7 +145,7 @@ class ProductsService
|
||||
$productsImagesMap = [];
|
||||
foreach ($productsImages as $item) {
|
||||
$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',
|
||||
];
|
||||
}
|
||||
@@ -157,16 +161,13 @@ class ProductsService
|
||||
'data' => array_map(function ($product) use ($productsImagesMap, $imageWidth, $imageHeight, $currency) {
|
||||
$allImages = [];
|
||||
|
||||
$image = $this->ocImageTool->resize(
|
||||
$product['product_image'],
|
||||
$imageWidth,
|
||||
$imageHeight,
|
||||
'placeholder.png'
|
||||
);
|
||||
$image = $this->image->make($product['product_image'])
|
||||
->resize($imageWidth, $imageHeight)
|
||||
->url();
|
||||
|
||||
$allImages[] = [
|
||||
'url' => $image,
|
||||
'alt' => Utils::htmlEntityEncode($product['product_name']),
|
||||
'alt' => Str::htmlEntityEncode($product['product_name']),
|
||||
];
|
||||
|
||||
$priceNumeric = $this->tax->calculate(
|
||||
@@ -197,7 +198,7 @@ class ProductsService
|
||||
return [
|
||||
'id' => (int) $product['product_id'],
|
||||
'product_quantity' => (int) $product['product_quantity'],
|
||||
'name' => Utils::htmlEntityEncode($product['product_name']),
|
||||
'name' => Str::htmlEntityEncode($product['product_name']),
|
||||
'price' => $price,
|
||||
'special' => $special,
|
||||
'image' => $image,
|
||||
@@ -251,13 +252,13 @@ class ProductsService
|
||||
$data['tab_review'] = sprintf($this->oc->language->get('tab_review'), $product_info['reviews']);
|
||||
|
||||
$data['product_id'] = $productId;
|
||||
$data['name'] = Utils::htmlEntityEncode($product_info['name']);
|
||||
$data['name'] = Str::htmlEntityEncode($product_info['name']);
|
||||
$data['manufacturer'] = $product_info['manufacturer'];
|
||||
$data['model'] = $product_info['model'];
|
||||
$data['reward'] = $product_info['reward'];
|
||||
$data['points'] = (int) $product_info['points'];
|
||||
$data['description'] = Utils::htmlEntityEncode($product_info['description']);
|
||||
$data['share'] = Utils::htmlEntityEncode(
|
||||
$data['description'] = Str::htmlEntityEncode($product_info['description']);
|
||||
$data['share'] = Str::htmlEntityEncode(
|
||||
$this->oc->url->link('product/product', 'product_id=' . $productId)
|
||||
);
|
||||
|
||||
@@ -281,23 +282,16 @@ class ProductsService
|
||||
$images = [];
|
||||
foreach ($allImages as $imagePath) {
|
||||
try {
|
||||
[$width, $height] = $this->ocImageTool->getRealSize($imagePath);
|
||||
[$width, $height] = $this->image->make($imagePath)->getRealSize();
|
||||
$images[] = [
|
||||
'thumbnailURL' => $this->ocImageTool->resize(
|
||||
$imagePath,
|
||||
$imageThumbWidth,
|
||||
$imageThumbHeight,
|
||||
'placeholder.png'
|
||||
),
|
||||
'largeURL' => $this->ocImageTool->resize(
|
||||
$imagePath,
|
||||
$imageFullWidth,
|
||||
$imageFullHeight,
|
||||
'placeholder.png'
|
||||
),
|
||||
'thumbnailURL' => $this->image
|
||||
->make($imagePath)
|
||||
->resize($imageThumbWidth, $imageThumbHeight)
|
||||
->url(),
|
||||
'largeURL' => $this->image->make($imagePath)->resize($imageFullWidth, $imageFullHeight)->url(),
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'alt' => Utils::htmlEntityEncode($product_info['name']),
|
||||
'alt' => Str::htmlEntityEncode($product_info['name']),
|
||||
];
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Handlers\ETLHandler;
|
||||
use App\Handlers\FiltersHandler;
|
||||
use App\Handlers\FormsHandler;
|
||||
use App\Handlers\HealthCheckHandler;
|
||||
use App\Handlers\ImageHandler;
|
||||
use App\Handlers\OrderHandler;
|
||||
use App\Handlers\PrivacyPolicyHandler;
|
||||
use App\Handlers\ProductsHandler;
|
||||
@@ -22,6 +23,7 @@ return [
|
||||
'filtersForMainPage' => [FiltersHandler::class, 'getFiltersForMainPage'],
|
||||
'getCart' => [CartHandler::class, 'index'],
|
||||
'getForm' => [FormsHandler::class, 'getForm'],
|
||||
'getImage' => [ImageHandler::class, 'getImage'],
|
||||
'health' => [HealthCheckHandler::class, 'handle'],
|
||||
'ingest' => [TelemetryHandler::class, 'ingest'],
|
||||
'heartbeat' => [TelemetryHandler::class, 'heartbeat'],
|
||||
|
||||
Reference in New Issue
Block a user