activeCategory = $activeCategory; $this->wrapper = $wrapper; $this->pathFinder = $pathFinder; $this->productList = $productList; $this->proxyCacheEnabled = findModule(\Modules::PROXY_CACHE, 'product'); } public function getHeaderVariables() { $header = parent::getHeaderVariables(); if ($this->getSearchString()) { $header['searchString'] = $this->getSearchString(); } return $header; } public function getBodyVariables() { $this->checkProductExist(); if (findModule(\Modules::COMPONENTS)) { $product = $this->getProduct(); $this->productDataProvider->addProduct($product); $vars['id_product'] = $this->productId; $vars['id_variation'] = intval(getVal('id_variation')) ?: null; // TODO: HACK!!!!! } else { $vars = parent::getBodyVariables(); if ($this->search()) { $vars['search'] = $this->search(); } $vars['product'] = $this->wrapper->setObject($this->getProduct()); $vars['productCollection'] = $this->productCollection; } return $vars; } public function getDeliveries() { return \DeliveryType::getDeliveries(); } public function getSearchString() { if ($this->request->get('search') != null && trim($this->request->get('search')) != '') { $search = trim($this->request->get('search')); return $search; } return false; } public function search() { if ($this->getSearchString()) { $search = trim($this->getSearchString()); $word = []; $word = preg_split('/[[:blank:]]+/', $search); if (count($word) > 0) { for ($i = 0; $i < count($word); $i++) { if (trim($word[$i]) == '') { unset($word[$i]); } $word[$i] = preg_quote($word[$i]); } } return $word; } return false; } public function getBreadcrumbs(): array { $returnNav = []; $navArray = null; $product = $this->getProduct(); $qb = sqlQueryBuilder() ->select('ps.id_section') ->from('products_in_sections', 'ps') ->join('ps', 'sections', 's', 'ps.id_section = s.id') ->where(Operator::equals(['id_product' => $product->id])) ->andWhere(Operator::not(Operator::equals(['s.figure' => 'N']))) ->orderBy('s.priority', 'DESC') ->execute(); foreach ($qb as $index => $row) { $navArray = getReturnNavigation($row['id_section'], 'PRODUCT', [$product->title]); if ($index == 0) { // Set opened menu section - first available section if ($this->activeCategory->loadCategoryId() == null) { $this->activeCategory->setCategoryId($row['id_section']); } } $returnNav = array_merge($returnNav, $navArray); if ($this->activeCategory->loadCategoryId() == null) { $this->activeCategory->setCategoryId($row['id_section']); } } return $returnNav; } public function getBreadcrumbsNew(): array { $returnNav = $this->getSectionsBreadcrumbs(); return reset($returnNav); } public function getSectionsBreadcrumbs(): array { if ($this->sectionsBreadcrumbsCache) { return $this->sectionsBreadcrumbsCache; } $returnNav = []; $product = $this->getProduct(); $home = [ 'text' => translate('getSections', 'functions')['home'], 'link' => path('home'), ]; $this->productDataProvider->multiFetch()->fetchSectionsDirectly(); $sections = $product->fetchSections(); if (!is_array($sections)) { $sections = [$sections]; } /** @var Section $section */ foreach (array_values($sections) as $index => $section) { $navArray = [$home]; foreach ($section->getParents() as $parent) { $navArray[] = [ 'text' => $parent->getNameShort() ?: $parent->getName(), 'section_name' => $parent->getName(), 'link' => '/'.$parent->getUrl(), 'ID' => $parent->getId(), ]; } $navArray[] = ['text' => $product->title]; if ($index == 0) { // Set opened menu section - first available section if ($this->activeCategory->loadCategoryId() == null) { $this->activeCategory->setCategoryId($section->getId()); } } $returnNav[] = $navArray; if ($this->activeCategory->loadCategoryId() == null) { $this->activeCategory->setCategoryId($section->getId()); } } if (empty($returnNav)) { $returnNav[] = [$home, ['text' => $product->title]]; } $this->sectionsBreadcrumbsCache = $returnNav; return $this->sectionsBreadcrumbsCache; } public function getDeliveryDays() { $days = sqlQueryBuilder()->select('MAX(time_days) as days')->from('delivery_type_delivery')->execute()->fetch(); if ($days) { $days = ['min' => $days['days']]; } if (findModule(\Modules::DELIVERY_PRICELIST)) { $priceList = ServiceContainer::getService(\KupShop\DeliveryPriceListBundle\DeliveryPriceCalculator::class); $countryContext = ServiceContainer::getService(\KupShop\KupShopBundle\Context\CountryContext::class); $days = $priceList->getDeliveryTime($countryContext->getActiveId()); } return $days; } public function checkProductExist() { if (!$this->getProduct()) { throw new NotFoundHttpException('Product not found'); } } public function getProduct() { if ($this->product === null) { $productList = $this->productList; $productList->applyDefaultFilterParams(); $productList->andSpec(function (QueryBuilder $qb) { $qb->andWhere(Operator::equals(['p.id' => $this->getProductId()])) ->addSelect('pv.id as variation_id') ->having('figure = "Y"') ->andWhere( Translation::coalesceTranslatedFields( ProductsTranslation::class, ['long_descr', 'parameters', 'meta_title', 'meta_description', 'meta_keywords', 'figure'] )); $qb->addSelect(\Query\Product::withProductPhotoId()); }); if (!findModule(\Modules::COMPONENTS)) { $productList->fetchSections()->fetchProductLabels('detail'); } $products = $productList->getProducts(); // pokud se v produkt nevrati z ProductListu tak je neco spatne if (!($this->product = $products->first())) { $visible = false; // zkusim vytvorit produkt pres class product $this->product = new \Product(); // kdyz produkt neexistuje vrat 404 if (!$this->product->createFromDB($this->getProductId())) { // nastavim na false, protoze jsem produkt nenasl a pri pripadnym dalsim volani uz ho nechci zkouset znova nacitat $this->product = false; return false; } $products = new ProductCollection([$this->product->id => $this->product]); $multiFetch = ServiceContainer::getService(\KupShop\CatalogBundle\ProductList\MultiFetch::class); $multiFetch->fetchSections($products); $multiFetch->fetchProductLabels($products, 'detail'); // pro admina nezobrazovat 404, pokud je produkt skryty if (getAdminUser()) { $visible = true; } $dbcfg = \Settings::getDefault(); $doNotShowProductsNotInStore = $dbcfg->prod_show_not_in_store === 'N'; $productIsNotInStore = $this->product->inStore <= 0 && $this->product->getInStoreSuppliers() <= 0; // nastavit produkt vyprodan/prodej ukoncen, pokud neni skladem a neni zaskrtnuto Zobrazit zboží, které není skladem if ($this->product->isVisible() && ($this->product->isOld() || ($doNotShowProductsNotInStore && $productIsNotInStore))) { $this->product->visible = 'O'; } if ($this->product->visible == 'O') { $visible = true; } if (!$visible) { // nastavim na false, protoze jsem produkt nenasl a pri pripadnym dalsim volani uz ho nechci zkouset znova nacitat $this->product = false; return false; } // ProductList uz to jako jediny vola, tady musime zavolat rucne $this->product->prepareDeliveryText(); } $this->productCollection = $products; if (!findModule(\Modules::COMPONENTS)) { $this->product->fetchProducer(); $this->product->fetchParameters(); $this->product->fetchVariations(); $this->product->fetchLinks(); $this->product->fetchAttachments(); $this->product->fetchImages(3, 4); $this->product->fetchSets(); $this->product->fetchGifts(); if (findModule(\Modules::BONUS_PROGRAM)) { $this->product->fetchBonusPoints(); } } $sections = array_map(function ($section) { return $section->getId(); }, $this->product->sections ?? []); $this->activeCategory->validate($sections, $this->product->id); } return $this->product; } public function getShowInSearch(): bool { return $this->getProduct() && ($this->getProduct()->showInSearch === 'Y'); } public function getTitle() { return $this->getProduct()->title; } public function getWpjToolbar() { $arr = [ 'url' => getAdminUrl('products', ['ID' => $this->getProductId()]), 'title' => 'Upravit produkt', 'translateUrl' => getAdminUrl('list', [ 'type' => 'translateProducts', 'iframe' => 1, 'objectIDs' => $this->getProductId(), ]), 'translateTitle' => 'Překlad produktu', ]; return array_merge(parent::getWpjToolbar(), $arr); } public function setProductId($id) { $this->productId = $id; } public function getProductId() { return $this->productId; } public function getMetaTitle() { if (!empty($this->getProduct()->meta_title)) { return $this->getProduct()->meta_title; } return $this->getTitle(); } public function getMetaKeywords() { return $this->getProduct()->meta_keywords; } public function getMetaDescription() { $product = $this->getProduct(); // Get meta description from product if (!empty($product->meta_description)) { return $product->meta_description; } // Get first 160 chars (entire words) from description+ if (findModule(\Modules::PRODUCTS, \Modules::SUB_DESCR_PLUS)) { if ($product->id_block) { $content = $this->block->getBlockContent($product->id_block, true); if (!empty($content)) { return StringUtil::replacePunctuationWithPeriod(StringUtil::cutToWords($content, 160)); } } } // Get first 160 chars from product description if (!empty($product->longDescr)) { $content = strip_tags($product->longDescr); $content = preg_replace("/[\n]/i", ' ', $content); $content = StringUtil::normalizeWhitespace($content); if (!empty($content)) { return StringUtil::replacePunctuationWithPeriod(StringUtil::cutToWords($content, 160)); } } // Get first 160 chars from producer description $producer = $product->fetchProducer(); if (!empty($producer['id_block'])) { $content = $this->block->getBlockContent($producer['id_block'], true); if (!empty($content)) { return StringUtil::replacePunctuationWithPeriod(StringUtil::cutToWords($content, 160)); } } // Get meta description from producer $description = $producer['meta_description'] ?? ''; if (!empty($description)) { return StringUtil::replacePunctuationWithPeriod(StringUtil::cutToWords($description, 160)); } // Get eshop default meta description return \Settings::getDefault()->shop_description; } public function getCorrectUrl(): ?string { if (!$this->getProduct()) { return null; } return path('products', ['id' => $this->getProduct()->id, 'name' => StringUtil::slugify($this->getProduct()->title)]); } protected function getLastModifiedDate(): \DateTime { $productId = $this->getProductId(); if ($productId) { $date = sqlQueryBuilder()->select('updated') ->from('products') ->where(Operator::equals(['id' => $productId])) ->execute()->fetchOne(); if ($date) { return new \DateTime($date); } } return parent::getLastModifiedDate(); } public function getPlaceholders(): iterable { return $this->placeholders ??= [ new Placeholder('POCET_BODU', 'Počet bodů získaných nákupem produktu', function () { return $this->getProduct()->getBonusPoints()?->printFloatValue(-2) ?? ''; }), new Placeholder('DOPRAVA_ZDARMA_OD', 'Částka, od které je doprava zdarma', function () { $purchaseUtil = ServiceContainer::getService(PurchaseUtil::class); $freeDeliveryFrom = $purchaseUtil->getFreeDeliveryFrom(true); if (Contexts::get(UserContext::class)->getActive()) { $freeDeliveryFrom = $freeDeliveryFrom['registered']; } else { $freeDeliveryFrom = $freeDeliveryFrom['unregistered']; } if ($freeDeliveryFrom === false) { return ''; } return printPrice($freeDeliveryFrom); }), ]; } #[Required] final public function setSectionsRepository(?SectionsRepository $sectionsRepository): void { $this->sectionsRepository = $sectionsRepository; } public function getTemplates(): iterable { yield $this->template; // yield 'product.old.tpl'; // TODO: Co s touhle šablonou? Zrušit? } }