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, ] ); } }