first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
<?php
/**
* Created by PhpStorm.
* User: leos
* Date: 8/1/17
* Time: 3:26 PM.
*/
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\AccountView;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
class AccountController extends AbstractController
{
/**
* @TranslatedRoute("/#account#/", name="account")
*/
public function accountAction(Request $request, AccountView $view)
{
$view->setRequest($request);
return $view->getResponse();
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\ArticlesView;
use KupShop\ContentBundle\View\ArticleView;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
class ArticlesController extends AbstractController
{
/**
* @TranslatedRoute("/#articles#/{IDb}/{param}/{IDa}/", requirements={"IDb":"\d+", "IDa":"\d+", "param":"(prev|next)"})
* @TranslatedRoute("/#articles#/{IDb}/{slug}/{param}/{IDa}/", requirements={"IDb":"\d+", "IDa":"\d+", "slug":".*", "param":"(prev|next)"})
*/
public function articlePrevNext(Request $request, ArticlesView $view, $IDa, $IDb, $param)
{
$view->setIDb($IDb);
$view->setRequest($request);
$ArticleID = $view->getPrevNext($IDa, $param);
return new RedirectResponse(
path('kupshop_content_articles_article', ['IDa' => $ArticleID])
);
}
/**
* @TranslatedRoute("/#articles#/")
* @TranslatedRoute("/#articles#/{IDb}/", requirements={"IDb":"\d+"})
* @TranslatedRoute("/#articles#/{IDb}/{slug}/", requirements={"IDb":"\d+", "slug":".*"})
*/
public function articlesAction(Request $request, ArticlesView $view, $IDb = null): ArticlesView
{
if ($IDb) {
$view->setIDb($IDb);
}
$this->setArticlesFilters($request, $view);
$view->setRequest($request);
return $view;
}
/**
* @TranslatedRoute("/#articles#/#tag#/{tagId}/", requirements={"tagId":"\d+"})
* @TranslatedRoute("/#articles#/#tag#/{tagId}/{slug}/", requirements={"tagId":"\d+", "slug":".*"})
*/
public function articlesTagsAction(Request $request, ArticlesView $view, int $tagId): ArticlesView
{
$this->setArticlesFilters($request, $view);
$view->setTagId($tagId);
$view->setRequest($request);
return $view;
}
/**
* @TranslatedRoute("/#articles#/#author#/{authorId}/", requirements={"authorId":"\d+"}, module="articles_authors")
* @TranslatedRoute("/#articles#/#author#/{authorId}/{slug}/", requirements={"authorId":"\d+", "slug":".*"}, module="articles_authors")
*/
public function articlesAuthorAction(Request $request, ArticlesView $view, int $authorId): ArticlesView
{
$this->setArticlesFilters($request, $view);
$view->setAuthorId($authorId);
$view->setRequest($request);
return $view;
}
/**
* @TranslatedRoute("/#article#/{IDa}/", requirements={"IDa":"\d+"})
* @TranslatedRoute("/#article#/{IDa}/{slug}/", requirements={"IDa":"\d+", "slug":".*"})
*/
public function articleAction(Request $request, ArticleView $view, $IDa)
{
$view->setIDa($IDa);
$view->setRequest($request);
return $view;
}
private function setArticlesFilters(Request $request, ArticlesView $view): void
{
// razeni produktu
$view->setSort(
$request->get('order')
);
// dynamicke filtry
$view->setDynamicFilter(
$request->get('dynamic_filter', [])
);
}
}

View File

@@ -0,0 +1,571 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\AdminBundle\Util\BlocksHistory;
use KupShop\CDNBundle\CDN;
use KupShop\ContentBundle\Util\BlocekSettings;
use KupShop\ContentBundle\Util\Block;
use KupShop\ContentBundle\View\BlockEditView;
use KupShop\ContentBundle\View\BlockHistoryView;
use KupShop\I18nBundle\Translations\PhotosTranslation;
use KupShop\KupShopBundle\Query\JsonOperator;
use KupShop\KupShopBundle\Util\Functional\Mapping;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\KupShopBundle\Util\StringUtil;
use KupShop\KupShopBundle\Util\System\PathFinder;
use Query\Operator;
use Query\QueryBuilder;
use Query\Translation;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
class BlockController extends AbstractController
{
use \DatabaseCommunication;
public function __construct(protected ?CDN $cdn = null)
{
}
/**
* @Route("/_blocek/upload/")
*/
public function uploadAction(Request $request)
{
try {
$this->doCheckPermissions();
} catch (\Exception $e) {
return new JsonResponse([
'result' => false,
'error' => $e->getMessage(),
]);
}
$result = false;
$message = null;
try {
$result = sqlGetConnection()->transactional(
function () use ($request) {
$uploadedIds = [];
$photos = new \Photos('none');
/** @var UploadedFile $file */
foreach ($request->files->get('file', []) as $file) {
$data = [
'name' => $file->getClientOriginalName(),
'tmp_name' => $file->getRealPath(),
];
$photos->newImage();
$photos->uploadImage($data);
$photoId = $photos->insertImageIntoDB();
if (!$photoId) {
throw new \Exception('Nahrání se nepodařilo, zkuste to znovu.');
}
$uploadedIds[] = $photoId;
}
return $uploadedIds;
}
);
} catch (\Exception $e) {
$message = $e->getMessage();
}
return new JsonResponse([
'result' => $result,
'message' => $message,
]);
}
#[Route('/_blocek/video-info/')]
public function videoInfoAction(Request $request, PathFinder $pathFinder): JsonResponse
{
$result = false;
$message = null;
$data = [];
try {
if (!findModule(\Modules::CDN) || !$this->cdn) {
throw new \Exception('Není povolen modul CDN!');
}
$videos = $this->getPhotosData((array) $request->get('videoId', []), function (QueryBuilder $qb) {
$qb->leftJoin('ph', 'videos', 'v', 'ph.id = v.id_photo');
$qb->addSelect('v.*');
});
foreach ($videos as $video) {
if (!$video['id_cdn']) {
throw new \Exception('Video není nahráno v CDN!');
}
$data[] = [
'id' => (int) $video['id'],
'title' => $video['descr'],
'id_cdn' => $video['id_cdn'],
'url_mp4' => $this->cdn->getMP4Video($video['id_cdn'], '720p'),
'url_hls' => $this->cdn->getHLSPlaylist($video['id_cdn']),
'thumbnail' => $this->cdn->getThumbnail($video['id_cdn'])['url'],
];
}
$result = true;
} catch (\Exception $e) {
$message = $e->getMessage();
$data = [];
}
return $this->jsonResponse(result: $result, data: $data, message: $message);
}
/**
* @Route("/_blocek/photo-info/")
*/
public function photoInfoAction(Request $request, PathFinder $pathFinder): JsonResponse
{
$result = false;
$message = null;
$data = [];
try {
foreach ($this->getPhotosData((array) $request->get('photoId', [])) as $photo) {
$file = $pathFinder->getDataDir().'photos/'.$photo['source'].$photo['image_2'];
if (!file_exists($file)) {
throw new \Exception('Obrázek nebyl nalezen!');
}
[$width, $height] = getimagesize($file);
$data[] = [
'id' => (int) $photo['id'],
'width' => $width,
'height' => $height,
'timestamp' => filemtime($file),
'title' => $photo['descr'],
];
}
$result = true;
} catch (\Exception $e) {
$message = $e->getMessage();
$data = [];
}
return $this->jsonResponse(result: $result, data: $data, message: $message);
}
private function jsonResponse(bool $result, array $data, ?string $message = null): JsonResponse
{
return new JsonResponse(
[
'result' => $result,
'message' => $message,
'data' => $data,
],
200,
[
'Access-Control-Allow-Origin' => '*',
]
);
}
private function getPhotosData(array $ids, ?callable $specs = null): array
{
$photos = sqlQueryBuilder()
->select('ph.*')
->from('photos', 'ph')
->andWhere(Operator::inIntArray($ids, 'ph.id'))
->andWhere(Translation::coalesceTranslatedFields(PhotosTranslation::class));
if ($specs) {
$photos->andWhere($specs);
}
return $photos->execute()->fetchAllAssociative();
}
/**
* @Route("/_blocek/edit-block/{id}/")
*/
public function editBlockAction(Request $request, Block $block, BlockEditView $blockEditView, $id)
{
$blockEditView->setBlockId($id);
return $blockEditView->getResponse();
}
/**
* @Route("/_blocek/history-block/{historyId}/{blockId}/")
*/
public function historyBlockAction(Request $request, Block $block, BlockHistoryView $blockHistoryView, $historyId, $blockId)
{
$blockHistoryView->setBlockId($blockId);
$blockHistoryView->setHistoryId($historyId);
return $blockHistoryView->getResponse();
}
/**
* @Route("/_blocek/save-block/")
*/
public function saveBlockAction(Request $request, SentryLogger $sentryLogger, BlocksHistory $blocksHistory, Block $blockUtil)
{
try {
$this->doCheckPermissions();
} catch (\Exception $e) {
return new JsonResponse([
'result' => false,
'error' => $e->getMessage(),
]);
}
$data_array = json_decode($request->getContent(), true);
try {
$result = sqlGetConnection()->transactional(
function () use ($blockUtil, $data_array, $blocksHistory) {
foreach ($data_array as $data) {
if ($data['id_block'] = $this->getBlockId($blockUtil,
$data['id_block'] ?: null,
$data['object_type'] ?: null,
$data['object_id'] ?: null)) {
// get images blocks
$imagesBlocks = $this->getImageBlocks(json_decode($data['json_content'], true));
$language = ($data['id_language'] ?? null);
$data['json_content'] = json_encode(json_decode($data['json_content'], true));
$data['content'] = StringUtil::unicodeToEntities($data['content']);
if (!$language) {
$block = ['id' => $data['id_block'], 'name' => '', 'content' => $data['content']];
$blocksHistory->saveBlocksHistory([$data['id_block'] => $block]);
// save content
sqlQueryBuilder()->update('blocks')
->directValues(
[
'json_content' => $data['json_content'],
'content' => $data['content'],
]
)
->where(Operator::equals(['id' => $data['id_block']]))
->execute();
$rootId = sqlQueryBuilder()->select('id_root')->from('blocks')
->where(Operator::equals(['id' => $data['id_block']]))
->execute()->fetchColumn();
$pageID = sqlQueryBuilder()->select('id')->from('pages')
->where(Operator::equals(['id_block' => $rootId]))
->execute()->fetchColumn();
if ($pageID) {
$this->updateSQL('pages', ['updated' => date('Y-m-d H:i:s')], ['id' => $pageID]);
}
} else {
// save content - translations
$originalName = sqlQueryBuilder()->select('name')->from('blocks_translations')
->where(Operator::equals([
'id_block' => $data['id_block'],
'id_language' => $data['id_language'],
]))->setMaxResults(1)->execute()->fetchColumn(0);
if ($originalName === false) {
$this->insertSQL('blocks_translations',
[
'id_block' => $data['id_block'],
'id_language' => $data['id_language'],
'json_content' => $data['json_content'],
'content' => $data['content'],
]);
} else {
$this->updateSQL('blocks_translations',
[
'name' => $originalName,
'json_content' => $data['json_content'],
'content' => $data['content'],
'updated' => date('Y-m-d H:i:s'),
],
[
'id_block' => $data['id_block'],
'id_language' => $data['id_language'],
]);
}
}
// create photos relations
sqlQueryBuilder()->delete('photos_blocks_new_relation')
->where(Operator::equals(['id_block' => $data['id_block']]))
->execute();
if (!empty($imagesBlocks)) {
foreach ($imagesBlocks as $imageBlock) {
if (isset($imageBlock['settings']['photo'])) {
$imageBlock['settings']['photos'][0]['photo'] = $imageBlock['settings']['photo'];
}
$photos = $imageBlock['settings']['photos'];
foreach ($photos as $ph) {
try {
$photoId = $ph['photo']['id'];
sqlQueryBuilder()
->insert('photos_blocks_new_relation')
->directValues(
[
'id_photo' => $photoId,
'id_block' => $data['id_block'],
]
)->execute();
} catch (\Exception $e) {
}
}
}
}
} else {
throw new \Exception('Nor id_block, object_type or object_id specified!');
}
}
return true;
}
);
} catch (\Exception $e) {
$sentryLogger->captureException($e);
return new JsonResponse([
'result' => false,
'error' => $e->getMessage(),
]);
}
return new JsonResponse([
'result' => $result,
]);
}
protected function getBlockId(Block $blockUtil, ?int $id_block, ?string $objectType, ?int $objectId)
{
if ($id_block ?? false) {
return $id_block;
}
if (!$objectType || !$objectId) {
return false;
}
return $blockUtil->insertFirstBlock($objectType, $objectId, '');
}
public function getImageBlocks($settings)
{
$result = [];
foreach ($settings as $setting) {
$imageBlocks = array_filter(
$settings,
function ($x) {
return isset($x['settings']['photo']) || isset($x['settings']['photos']);
}
);
$result = array_merge($result, $imageBlocks);
if (!empty($setting['children'])) {
$result = array_merge($result, $this->getImageBlocks($setting['children']));
}
}
return $result;
}
public function doCheckPermissions()
{
if (!getAdminUser()) {
throw new NotFoundHttpException('Platnost přihlášení vypršela');
}
}
/**
* @Route("/_blocek/ProductsBlock/")
*/
public function getProductsAction(Request $request, Block $blockUtil)
{
if (!$request->getContent()) {
throw new NotFoundHttpException('Empty data');
}
$blocekData = json_decode_strict($request->getContent(), true);
$filterSpecs = $blockUtil->getProductsBlockSpecs($blocekData);
$smarty = createSmarty(false, true);
$smarty->assign('spec', $filterSpecs);
$smarty->assign('data', $blocekData);
$response['html'] = $smarty->fetch('block.products.blocek.tpl');
$response['result'] = true;
$response['filter'] = $blocekData;
// Detect empty product list in edit mode
if ($request->get('editor') && strpos($response['html'], 'href') === false) {
$response['result'] = false;
}
return new JsonResponse($response);
}
protected function getOrderDir($order_dir)
{
$order_dir = trim($order_dir);
if (($order_dir != 'ASC') && ($order_dir != 'DESC')) {
$order_dir = 'ASC';
}
return $order_dir;
}
protected function getOrderFields($order_by)
{
switch ($order_by) {
case 'code':
$order = 'p.code';
break;
case 'title':
$order = 'p.title';
break;
case 'price':
$order = 'p.price';
break;
case 'date':
$order = 'p.date_added';
break;
case 'sell':
$order = 'p.pieces_sold';
break;
case 'discount':
$order = 'p.discount';
break;
case 'store':
$order = 'p.in_store';
break;
case 'random':
$order = 'RAND()';
break;
default:
$order = 'p.title';
break;
}
return $order;
}
#[Route('/_blocek/settings/')]
public function getBlocekSettings(BlocekSettings $blocekSettings): JsonResponse
{
$blocekSettings->fetchSettings();
return new JsonResponse(['message' => 'BlocekSettings', 'data' => $blocekSettings->asArray()]);
}
/**
* @Route("/_blocek/templates/")
*/
public function getTemplatesAction(Block $blockUtils)
{
$message = null;
$data = [];
if (!findModule(\Modules::TEMPLATES)) {
return new JsonResponse(
[
'message' => 'No templates module',
'data' => $data,
]
);
}
$qb = sqlQueryBuilder()
->select('tc.*')
->from('templates_categories', 'tc')
->Where(Operator::like([JsonOperator::value('tc.data', 'show_in_editor') => 'Y']));
$templateCategories = sqlFetchAll($qb->execute(), 'id');
$templateCategoriesIDs = array_keys($templateCategories);
$templates = sqlQueryBuilder()
->select('t.*')
->from('templates', 't')
->where(Operator::inIntArray($templateCategoriesIDs, 't.id_category'));
foreach ($templates->execute() as $template) {
$blocks = $blockUtils->getBlocks($template['id_block']);
// beru obsah jen prvního bloku
if ($blocks[0]['content'] ?? false) {
$data[] = [
'name' => $template['name'],
'group' => $templateCategories[$template['id_category']]['name'],
'content' => json_decode($blocks[0]['json_content']),
];
}
}
return new JsonResponse(
[
'message' => $message,
'data' => $data,
]
);
}
#[Route('/_blocek/icons/')]
public function getIconsAction(Block $blockUtils): JsonResponse
{
$fontIcons = json_decode_strict(file_get_contents('web/build/icons-list.json'), true);
$fileIcons = new \GlobIterator('data/icons/*.svg', \FilesystemIterator::CURRENT_AS_PATHNAME);
$fileIcons = Mapping::mapKeys($fileIcons, fn ($fileName) => [basename('file-'.$fileName, '.svg'), '/'.$fileName]);
return new JsonResponse(
[
'success' => true,
'font_icons' => $fontIcons,
'file_icons' => $fileIcons,
]
);
}
#[Route('/_blocek/icons-inline/')]
public function getIconsInlineAction(Block $blockUtils): JsonResponse
{
if (!findModule(\Modules::COMPONENTS)) {
$fontIcons = json_decode_strict(file_get_contents('web/build/icons-list.json'), true);
}
$engineIcons = new \GlobIterator('engine/web/common/static/images/icons/*.svg', \FilesystemIterator::CURRENT_AS_PATHNAME);
$shopIcons = new \GlobIterator('data/icons/*.svg', \FilesystemIterator::CURRENT_AS_PATHNAME);
$fileIcons = [];
// Apparently, its not necessary to strip doctype and xml tag, blocek lib will handle this.
// foreach ($engineIcons as $iconPath) {
// $icon = Icon::fromFile($iconPath);
// $fileIcons[basename($iconPath, '.svg')] = $icon->toHtml();
// }
// foreach ($shopIcons as $iconPath) {
// $icon = Icon::fromFile($iconPath);
// $fileIcons[basename($iconPath, '.svg')] = $icon->toHtml();
// }
foreach ($engineIcons as $iconPath) {
$fileIcons[basename($iconPath, '.svg')] = file_get_contents($iconPath);
}
foreach ($shopIcons as $iconPath) {
$fileIcons[basename($iconPath, '.svg')] = file_get_contents($iconPath);
}
return new JsonResponse(
[
'success' => true,
'font_icons' => $fontIcons ?? [],
'file_icons' => $fileIcons,
]
);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\CartView;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use KupShop\KupShopBundle\Util\RequestUtil;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
class CartController extends AbstractController
{
/**
* @TranslatedRoute("/#cart#/{step}/")
* @TranslatedRoute("/#cart#/", defaults={"step":"cart"})
*/
public function cartAction(Request $request, CartView $view, RequestUtil $requestUtil, $step)
{
$view->setStepName($step);
$view->setRequest($request);
$requestUtil->addTransactionInfo($request, ['step' => $step]);
if ($request->get('SubmitOrder', false)) {
$requestUtil->addTransactionInfo($request, ['action' => 'submit']);
}
return $view->getResponse();
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\Util\CartMerge;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class CartMergeController extends AbstractController
{
/**
* @Route("/cart-merge/")
*/
public function cartMergeAction(Request $request, CartMerge $cartMerge)
{
// Temporary log
/** @var LoggerInterface $logger */
$logger = ServiceContainer::getService('logger');
$logger->notice('Cart merge url', ['url' => $request->getUri(), 'referer' => $request->headers->get('referer')]);
$cartId = $request->get('cartId');
if ($cartId) {
$cartMerge->merge($cartId);
}
return new RedirectResponse(path('kupshop_content_cart_cart_1'));
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\ContactFormView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
class ContactFormController extends AbstractController
{
/**
* @Route(path="/formulare/{type}/", defaults={"type"="kontakt", "old"=false})
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function SendFormAction(Request $request, ContactFormView $view, $type, $old = false)
{
if (findModule(\Modules::COMPONENTS)) {
throw new NotFoundHttpException();
}
$view->setRequest($request);
$view->setFormType($type);
$view->setCompatibilityMode($old);
$view->setFormData(array_merge($request->query->all(), $request->request->all()));
if ($request->isMethod('POST')) {
if ($view->submitForm()) {
return new RedirectResponse(
path('kupshop_content_contactform_sendform_sent', ['type' => $type])
);
}
}
return $view->getResponse();
}
/**
* @Route(path="/formulare/{type}/odeslano", defaults={"type"="kontakt"}, name="kupshop_content_contactform_sendform_sent")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function SentAction(Request $request, ContactFormView $view, $type)
{
if (findModule(\Modules::COMPONENTS)) {
throw new NotFoundHttpException();
}
$view->setRequest($request);
$view->setFormType($type);
$view->setEmailSent(true);
$view->setFormData(array_merge($request->query->all(), $request->request->all()));
return $view->getResponse();
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* Created by PhpStorm.
* User: ondra
* Date: 11.10.17
* Time: 8:04.
*/
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\Error404View;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ErrorController extends AbstractController
{
/**
* @return Response
*
* @Route("/404/")
*/
public function error404Action(Request $request, Error404View $view)
{
$view->setRequest($request);
return $view->getResponse();
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\KupShopBundle\Views\View;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class FocusController extends AbstractController
{
#[Route('/_focus/lazy/{template}', requirements: ['template' => '[-_\w]+'])]
public function focusLazyAction(string $template, Request $request, View $view): Response
{
return $view
->setTemplate("focus_lazy/{$template}.tpl")
->setSmartyFallback('blank')
->addBodyVariables(iterator_to_array($request->query->getIterator()))
->getResponse();
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\HomeView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class HomeController extends AbstractController
{
#[Route('/', name: 'home')]
public function homeAction(Request $request, HomeView $view)
{
$view->setRequest($request);
return $view->getResponse();
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\AdminBundle\Util\SystemImageUtils;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Service\Attribute\Required;
class ImagesController extends AbstractController
{
#[Required]
public SystemImageUtils $systemImageUtils;
#[Route(
path: '/system-images/{filename}.{suffix}',
requirements: [
'filename' => '[a-zA-Z0-9\-]*',
'suffix' => 'png|svg|jpg|webmanifest',
]
)]
public function getSystemImages(string $filename, string $suffix): BinaryFileResponse|RedirectResponse
{
try {
return $this->systemImageUtils->getBinaryFileResponse($filename, $suffix);
} catch (FileNotFoundException $e) {
if (isDevelopment() && ($url = $this->systemImageUtils->getImageSrcRemote($filename, $suffix))) {
return new RedirectResponse($url);
}
throw $this->createNotFoundException("File /system-images/{$filename}.{$suffix} not found.");
}
}
#[Route(path: '/favicon.ico')]
public function getFaviconIco(): BinaryFileResponse|RedirectResponse
{
try {
return $this->systemImageUtils->getBinaryFileResponse('favicon', 'ico');
} catch (FileNotFoundException $e) {
if (isDevelopment() && ($url = $this->systemImageUtils->getImageSrcRemote('favicon', 'ico'))) {
return new RedirectResponse($url);
}
throw $this->createNotFoundException('File favicon.ico not found.');
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\Util\InstagramUtil;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class InstagramController extends AbstractController
{
/**
* @TranslatedRoute("/_kupshop/instagram/feed")
*/
public function feedAction(Request $request, InstagramUtil $instagramUtil)
{
if (!($callback = $request->query->get('callback'))) {
throw new NotFoundHttpException('Missing callback');
}
$count = $request->query->get('count');
$feed = $instagramUtil->getFeed($callback, $count);
$response = new Response($feed);
$response->headers->set('content-type', 'text/javascript; charset=utf-8');
$response->setClientTtl(3600);
$response->setExpires(new \DateTime('now + 1 hour'));
return $response;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\CatalogBundle\ProductList\ProductCollectionWrapper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
use Symfony\Component\Routing\Annotation\Route;
class LastVisitedController extends AbstractController
{
/**
* @Route("/_kupshop/lastvisited/")
*/
public function getLastVisitedAction(Request $request)
{
$jsonProducts = $request->get('products');
$products = array_filter($jsonProducts ? json_decode_strict($jsonProducts, true) : []);
$responseData = [
'html' => '',
'result' => true,
];
if ($products) {
$defaultParams = [
'type' => 'last_visited_stateless',
'template' => 'null',
'variations' => false,
'image' => 2,
'count' => 6,
'products' => $products,
];
$params = array_merge($defaultParams, $payload['params'] ?? []);
$products = ProductCollectionWrapper::wrap((new \InsertProductsTypes())->getProducts($params));
$smarty = createSmarty(false, true);
$smarty->assign('last_visited_products', ['products' => $products]);
$smarty->assign('listType', $request->get('listType'));
$smarty->assign('listId', $request->get('listId'));
$responseData['html'] = $smarty->fetch('components/block.products.last-visited.tpl');
}
$response = new JsonResponse($responseData);
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
$response->setMaxAge(0);
$response->setSharedMaxAge(60 * 10); // 10m
return $response;
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Views\AlwaysStreamedResponse;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
class LaunchController extends AbstractController
{
/**
* @Route("launch.php")
*/
public function launchAction(Request $request)
{
$response = new AlwaysStreamedResponse(function () use ($request) {
global $cfg, $dbcfg, $ctrl;
// Start session to avoid session problems
$request->getSession()->start();
if (isset($_GET['s']) && preg_match('/^[-_\.a-zA-Z0-9]+$/', $_GET['s'])) {
/** @var LoggerInterface $logger */
$logger = ServiceContainer::getService('logger');
$logger->error('LaunchController', [
'REQUEST_URI' => $_SERVER['REQUEST_URI'],
]);
$script = $_GET['s'].'.php';
} else {
throw new NotFoundHttpException();
}
if (file_exists($script)) {
require_once $script;
} else {
$script = $cfg['Path']['shared_version'].'web/'.$script;
if (file_exists($script)) {
require_once $script;
} else {
throw new NotFoundHttpException();
}
}
if (!empty($main_class)) {
/** @var Page $instance */
$instance = new $main_class();
$instance->run();
}
});
return $response;
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* Created by PhpStorm.
* User: ondra
* Date: 24.10.17
* Time: 11:04.
*/
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\NewsletterSubscribeView;
use KupShop\ContentBundle\View\NewsletterUnsubscribeView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class NewsletterController extends AbstractController
{
/**
* @return \Symfony\Component\HttpFoundation\Response
*
* @Route("/newsletter/subscribe/")
*/
public function subscribeAction(Request $request, NewsletterSubscribeView $view)
{
$view->setRequest($request);
return $view->getResponse();
}
/**
* @return \Symfony\Component\HttpFoundation\Response
*
* @Route("/newsletter/unsubscribe/")
*/
public function unsubscribeAction(Request $request, NewsletterUnsubscribeView $view)
{
$view->setRequest($request);
return $view->getResponse();
}
/**
* @Route("/newsletter/")
*/
public function otherAction(Request $request, NewsletterSubscribeView $subscribeView, NewsletterUnsubscribeView $unsubscribeView)
{
$id = intval(getVal('ID'));
$date = sqlFormatInput(getVal('date'));
if (getVal('subscribe') !== null) {
return $this->subscribeAction($request, $subscribeView);
} elseif (getVal('unsubscribe') !== null) {
return $this->unsubscribeAction($request, $unsubscribeView);
}
if (empty($id) || empty($date)) {
redirection('INDEX');
}
// ###############################
// LOAD NEWSLETTER
$text = '';
if (empty($text)) {
redirection('INDEX');
}
}
}

View File

@@ -0,0 +1,150 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\OrderEditView;
use KupShop\ContentBundle\View\OrderStatusView;
use KupShop\ContentBundle\View\OrderSuccessView;
use KupShop\ContentBundle\View\OrdersView;
use KupShop\ContentBundle\View\OrderView;
use KupShop\GraphQLBundle\EventListener\JsShopRefreshListener;
use KupShop\KupShopBundle\Exception\RedirectException;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use KupShop\OrderingBundle\Cart;
use KupShop\OrderingBundle\Util\Order\OrderUtil;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
class OrdersController extends AbstractController
{
/**
* @TranslatedRoute("/#orders#/", name="orders")
*/
public function ordersAction(Request $request, OrdersView $view)
{
$view->setRequest($request);
$filter = $request->get('filter', []);
$view->setFilter($filter);
return $view->getResponse();
}
/**
* @TranslatedRoute("/#orderView#/{id}/", requirements={"id":"\d+"})
*/
public function orderAction(Request $request, OrderView $view, OrderSuccessView $successView, $id)
{
if ($request->get('status') == '1') {
$view = $successView;
}
$view->setIDo($id);
$view->setRequest($request);
if ($error = $request->get('error')) {
$view->setError($error);
}
return $view;
}
/**
* @TranslatedRoute("/#orderView#/{id}/success/", requirements={"id":"\d+"})
*/
public function successAction(Request $request, OrderSuccessView $view, $id)
{
$view->setIDo($id);
$view->setRequest($request);
return $view->getResponse();
}
/**
* @TranslatedRoute("/#orderView#/{id}/storno/", requirements={"id":"\d+"})
*/
public function orderStornoAction(Request $request, $id)
{
OrderView::checkOrderOwnership($id, $request->get('cf'));
$order = new \Order();
$order->createFromDB($id);
if (in_array($order->status, getStatuses('editable'))) {
$order->setData('stornoByUser', true);
$order->storno(true);
}
$referer = $request->headers->get('referer', '/');
throw new RedirectException($referer);
}
/**
* @TranslatedRoute("/#orderStatus#/")
*/
public function orderStatusAction(Request $request, OrderStatusView $view)
{
$view->setRequest($request);
$view->setOrderId($request->get('IDo'));
return $view->getResponse();
}
/**
* @TranslatedRoute("/#orderView#/{id}/#orderEdit#/", requirements={"id":"\d+"})
*/
public function orderEditAction(Request $request, OrderEditView $view, $id)
{
$view->setRequest($request);
$view->setOrderId($id);
return $view->getResponse();
}
/**
* @TranslatedRoute("/#orderView#/{id}/change-payment/{payment}",
* requirements={"id":"\d+", "payment":"\d+"})
*/
public function orderPaymentChangeAction(Request $request, OrderView $view, $id, $payment)
{
$view->setIDo($id);
$view->setRequest($request);
if ($deliveryType = $view->canChangePayment($payment)) {
$view->changeDeliveryType($deliveryType);
addUserMessage(translate('payment_change', 'order'), 'success');
} else {
addUserMessage(translate('payment_change_false', 'order'));
}
$redirectUri = $request->headers->get('referer');
if (!$redirectUri) {
$redirectUri = $this->generateUrl('kupshop_content_orders_order', ['id' => $id]);
}
return new RedirectResponse($redirectUri);
}
/**
* @TranslatedRoute("/#orderView#/{id}/reorder/", requirements={"id":"\d+"})
*/
public function orderReorderAction(Request $request, OrderUtil $orderUtil, Cart $cart, $id)
{
OrderView::checkOrderOwnership($id, $request->get('cf'));
$order = new \Order();
$order->createFromDB($id);
$order->fetchItems();
$orderUtil->orderReorder($order, $cart);
if (findModule(\Modules::JS_SHOP)) {
$request->getSession()->set(JsShopRefreshListener::SESSION_NAME, true);
}
return new RedirectResponse(path('kupshop_content_cart_cart_1'));
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\PageView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class PageController extends AbstractController
{
public function pageAction(PageView $view, $id): PageView
{
$view->setMenuLinkId($id);
return $view;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\DeliveryTimeView;
use KupShop\ContentBundle\View\ProductView;
use KupShop\ContentBundle\View\VariationBlockView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractController
{
/**
* @Route("/{name}_z{id}/", name="products", requirements={"name":"([a-zA-Z0-9-]+)", "id":"([0-9]+)"})
*/
public function productAction(Request $request, ProductView $view, $id)
{
$view->setRequest($request);
$view->setProductId($id);
return $view;
}
/**
* @Route("/_shop/delivery/{idp}", requirements={"idp":"\d+"})
* @Route("/_shop/delivery/{idp}/{idv}", requirements={"idp":"\d+", "idv":"\d+"})
*/
public function variationDeliveryTimeAction(Request $request, DeliveryTimeView $view, $idp, $idv = null)
{
$view->setVariationId($idv);
$view->setProductId($idp);
return $view->getResponse();
}
/**
* @Route("/_shop/variation/{productId}/{variationId}/", requirements={"productId":"\d+", "variationId":"\d+"})
*/
public function variationFragmentAction(VariationBlockView $view, int $productId, int $variationId): Response
{
$view->setProductId($productId);
$view->setVariationId($variationId);
return $view->getResponse();
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\RedirectView;
use KupShop\KupShopBundle\Routing\SimpleTranslatedRoute;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
class RedirectController extends AbstractController
{
/**
* @TranslatedRoute(path="/#redir#/{type}/{id}/")
*
* @SimpleTranslatedRoute(path="/redir/")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function redirectAction(Request $request, RedirectView $view)
{
$view->setRequest($request);
if ($request->get('type')) {
$view->setType($request->get('type'));
}
if ($request->get('lang')) {
$view->setLang($request->get('lang'));
}
if ($request->get('id')) {
$view->setId($request->get('id'));
}
if ($request->get('inlineEdit')) {
$view->setEnableInlineEdit(true);
}
$view->setPermanent($request->get('permanent', false));
return $view->getResponse();
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\RobotstxtView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class RobotstxtController extends AbstractController
{
/**
* @var Response
*
* @return Response
*
* @Route("/robots.txt")
*/
public function robotstxtAction(RobotstxtView $view)
{
$response = $view->getResponse();
$response->headers->set('Content-Type', 'text/plain');
return $response;
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* Created by PhpStorm.
* User: ondra
* Date: 19.10.17
* Time: 11:16.
*/
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\Exception\UnknownSitemapTypeException;
use KupShop\ContentBundle\Util\SitemapLocator;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\CachingStreamedResponse;
use KupShop\KupShopBundle\Util\Contexts;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Router;
class SitemapController extends AbstractController
{
/**
* @Route("/sitemap.xml", name="kupshop_content_sitemap")
*/
public function sitemapIndexAction(SitemapLocator $sitemapLocator): Response
{
$writer = new \XMLWriter();
$writer->openMemory();
$writer->startDocument('1.0', 'UTF-8');
$writer->startElement('sitemapindex');
$writer->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
// sitemap parts
foreach ($this->getSitemaps($sitemapLocator) as $loc) {
$writer->startElement('sitemap');
$writer->writeElement('loc', $loc);
$writer->endElement();
}
$writer->endElement();
$response = new Response($writer->outputMemory(true));
$response->headers->set('Content-type', 'application/xml');
$response->headers->set('Content-type', 'text/xml; charset=utf-8');
return $response;
}
/**
* @Route("/{sequence}/sitemap_{type}.xml", name="kupshop_content_sitemap_sitemaptypesequence")
* @Route("/sitemap_{type}.xml", name="kupshop_content_sitemap_sitemaptype")
*/
public function sitemapTypeAction(Request $request, SitemapLocator $sitemapLocator, string $type, ?string $sequence = null): Response
{
try {
$sitemap = $sitemapLocator->getSitemap($type);
} catch (UnknownSitemapTypeException $e) {
throw new NotFoundHttpException($type);
}
$response = new CachingStreamedResponse();
$response->headers->set('Content-type', 'application/xml');
$response->headers->set('Content-type', 'text/xml; charset=utf-8');
$languageContext = Contexts::get(LanguageContext::class);
$cacheName = 'sitemap_'.$type;
if (findModule(\Modules::TRANSLATIONS)) {
$cacheName = 'sitemap_'.$type.'_'.$languageContext->getActiveId();
}
if (!empty($sequence)) {
$sitemap::setSequence($sequence);
$cacheName = $cacheName.'_'.$sequence;
}
$response->setCacheName($cacheName);
$response->setTtl(43200);
$response->setSkipCache($request->get('skip_cache', false));
$response->setCallback(function () use ($sitemap) {
$sitemap->render();
});
$response->initialize();
return $response;
}
public function getSitemaps(SitemapLocator $sitemapLocator): \Generator
{
foreach ($sitemapLocator->getTypes() as $type) {
try {
$sitemap = $sitemapLocator->getSitemap($type);
} catch (UnknownSitemapTypeException $e) {
throw new NotFoundHttpException($type);
}
if ($sitemap->hasSequences()) {
$countSequences = $sitemap->getCountSequences();
for ($i = 1; $i <= $countSequences; $i++) {
yield path('kupshop_content_sitemap_sitemaptypesequence', ['type' => $type, 'sequence' => $i], Router::ABSOLUTE_URL);
}
} else {
yield path('kupshop_content_sitemap_sitemaptype', ['type' => $type], Router::ABSOLUTE_URL);
}
}
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace KupShop\ContentBundle\Controller;
use KupShop\ContentBundle\View\UserMessageView;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class UserMessageController extends AbstractController
{
/**
* @return Response
*
* @TranslatedRoute("/#user-message#/")
*/
public function userMessageAction(UserMessageView $view)
{
return $view->getResponse();
}
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* Created by PhpStorm.
* User: ondra
* Date: 4.1.18
* Time: 9:16.
*/
namespace KupShop\ContentBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class VersionController extends AbstractController
{
/**
* @Route("/view/{type}/", name="kupshop_content_version_switchversion", requirements={"type"="desktop|default"})
*/
public function switchVersionAction(Request $request, $type)
{
$url = $request->headers->get('referer');
if (!$url) {
$url = '/';
}
$redirectResponse = new RedirectResponse($url);
switch ($type) {
case 'desktop':
$redirectResponse->headers->setCookie(new Cookie('web_version', '1'));
break;
case 'default':
$redirectResponse->headers->setCookie(new Cookie('web_version', '0'));
break;
}
return $redirectResponse;
}
}