/**
  * Display a wildcard in the back end
  *
  * @return string
  */
 public function generate()
 {
     if (TL_MODE == 'BE') {
         $objTemplate = new \BackendTemplate('be_wildcard');
         $objTemplate->wildcard = '### ISOTOPE ECOMMERCE: PRODUCT FILTERS ###';
         $objTemplate->title = $this->headline;
         $objTemplate->id = $this->id;
         $objTemplate->link = $this->name;
         $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id;
         return $objTemplate->parse();
     }
     $this->generateAjax();
     // Initialize module data.
     if (!$this->initializeFilters()) {
         return '';
     }
     // Hide product list in reader mode if the respective setting is enabled
     if ($this->iso_hide_list && Input::getAutoItem('product', false, true) != '') {
         return '';
     }
     $strBuffer = parent::generate();
     // Cache request in the database and redirect to the unique requestcache ID
     if ($this->blnUpdateCache) {
         $objCache = Isotope::getRequestCache()->saveNewConfiguration();
         // Include \Environment::base or the URL would not work on the index page
         \Controller::redirect(\Environment::get('base') . Url::addQueryString('isorc=' . $objCache->id, $this->jumpTo ?: null));
     }
     return $strBuffer;
 }
 /**
  * @inheritdoc
  */
 protected function findCurrent()
 {
     $alias = (string) Input::getAutoItem($this->getUrlKey(), false, true);
     if ('' === $alias) {
         return null;
     }
     /** @var PageModel $objPage */
     global $objPage;
     if (($calendars = FaqCategoryModel::findBy('jumpTo', $objPage->id)) === null) {
         return null;
     }
     return FaqModel::findPublishedByParentAndIdOrAlias($alias, $calendars->fetchEach('id'));
 }
 /**
  * @inheritdoc
  */
 protected function findCurrent()
 {
     $alias = (string) Input::getAutoItem($this->getUrlKey(), false, true);
     if ('' === $alias) {
         return null;
     }
     /** @var PageModel $objPage */
     global $objPage;
     if (($archives = NewsArchiveModel::findBy('jumpTo', $objPage->id)) === null) {
         return null;
     }
     // Fix Contao bug that returns a collection (see contao-changelanguage#71)
     $options = ['limit' => 1, 'return' => 'Model'];
     return NewsModel::findPublishedByParentAndIdOrAlias($alias, $archives->fetchEach('id'), $options);
 }
Example #4
0
 /**
  * Display a wildcard in the back end
  *
  * @return string
  */
 public function generate()
 {
     if (TL_MODE == 'BE') {
         $objTemplate = new \BackendTemplate('be_wildcard');
         $objTemplate->wildcard = '### ISOTOPE CHECKOUT ###';
         $objTemplate->title = $this->headline;
         $objTemplate->id = $this->id;
         $objTemplate->link = $this->name;
         $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id;
         return $objTemplate->parse();
     }
     $this->strCurrentStep = \Haste\Input\Input::getAutoItem('step');
     if ($this->strCurrentStep == '') {
         $this->redirectToNextStep();
     }
     return parent::generate();
 }
Example #5
0
 /**
  * Find all products we need to list.
  * @param   array|null
  * @return  array
  */
 protected function findProducts($arrCacheIds = null)
 {
     $arrIds = array(0);
     $objProduct = Product::findAvailableByIdOrAlias(Input::getAutoItem('product'));
     if (null === $objProduct) {
         return array();
     }
     $objRelated = RelatedProduct::findByProductAndCategories($objProduct, $this->iso_related_categories);
     if (null !== $objRelated) {
         while ($objRelated->next()) {
             $ids = trimsplit(',', $objRelated->products);
             if (!empty($ids) && is_array($ids)) {
                 $arrIds = array_unique(array_merge($arrIds, $ids));
             }
         }
     }
     $objProducts = Product::findAvailableByIds($arrIds, array('order' => \Database::getInstance()->findInSet(Product::getTable() . '.id', $arrIds)));
     return null === $objProducts ? array() : $objProducts->getModels();
 }
 /**
  * Add the html attribute to allowed elements
  *
  * @param \Template $objTemplate
  */
 public function parseTemplate($objTemplate)
 {
     if (!$objTemplate instanceof \FrontendTemplate || !$objTemplate->allowAjaxReload) {
         return;
     }
     // Determine whether we have a module or a content element by the vars given at this point
     if (\Module::findClass($objTemplate->type)) {
         $strType = 'mod';
     } elseif (\ContentElement::findClass($objTemplate->type)) {
         $strType = 'ce';
     } else {
         return;
     }
     // Some elements use the auto_item which we need to pass
     $strAutoItem = Input::getAutoItem('auto_item');
     // cssID is parsed in all common templates
     // Use cssID for our attribute
     $objTemplate->cssID .= sprintf(' data-ajax-reload-element="%s::%u"%s%s', $strType, $objTemplate->id, strlen($strAutoItem) ? sprintf(' data-ajax-reload-auto-item="%s"', $strAutoItem) : '', $objTemplate->ajaxReloadFormSubmit ? ' data-ajax-reload-form-submit=""' : '');
 }
Example #7
0
 /**
  * Generate module
  * @return void
  */
 protected function compile()
 {
     global $objPage;
     global $objIsotopeListPage;
     $objProduct = Product::findAvailableByIdOrAlias(\Haste\Input\Input::getAutoItem('product'));
     if (null === $objProduct) {
         $objHandler = new $GLOBALS['TL_PTY']['error_404']();
         $objHandler->generate($objPage->id);
         exit;
     }
     $arrConfig = array('module' => $this, 'template' => $this->iso_reader_layout ?: $objProduct->getRelated('type')->reader_template, 'gallery' => $this->iso_gallery ?: $objProduct->getRelated('type')->reader_gallery, 'buttons' => deserialize($this->iso_buttons, true), 'useQuantity' => $this->iso_use_quantity, 'jumpTo' => $objIsotopeListPage ?: $objPage);
     if (\Environment::get('isAjaxRequest') && \Input::post('AJAX_MODULE') == $this->id && \Input::post('AJAX_PRODUCT') == $objProduct->getProductId()) {
         $objResponse = new HtmlResponse($objProduct->generate($arrConfig));
         $objResponse->send();
     }
     $arrCSS = deserialize($objProduct->cssID, true);
     $this->Template->product = $objProduct->generate($arrConfig);
     $this->Template->product_id = $arrCSS[0] != '' ? ' id="' . $arrCSS[0] . '"' : '';
     $this->Template->product_class = trim('product ' . ($objProduct->isNew() ? 'new ' : '') . $arrCSS[1]);
     $this->Template->referer = 'javascript:history.go(-1)';
     $this->Template->back = $GLOBALS['TL_LANG']['MSC']['goBack'];
     $this->addMetaTags($objProduct);
     $this->addCanonicalProductUrls($objProduct);
 }
 /**
  * Display a wildcard in the back end
  *
  * @return string
  */
 public function generate()
 {
     if (TL_MODE == 'BE') {
         /** @var \BackendTemplate|object $objTemplate */
         $objTemplate = new \BackendTemplate('be_wildcard');
         $objTemplate->wildcard = '### ISOTOPE ECOMMERCE: CUMULATIVE FILTER ###';
         $objTemplate->title = $this->headline;
         $objTemplate->id = $this->id;
         $objTemplate->link = $this->name;
         $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id;
         return $objTemplate->parse();
     }
     // Hide product list in reader mode if the respective setting is enabled
     if ($this->iso_hide_list && Input::getAutoItem('product', false, true) != '') {
         return '';
     }
     if (empty($this->iso_cumulativeFields)) {
         return '';
     }
     return parent::generate();
 }
Example #9
0
 /**
  * Show product name in breadcrumb
  *
  * @param array  $arrItems
  * @param object $objModule
  *
  * @return array
  */
 public function addProductToBreadcrumb($arrItems, $objModule)
 {
     if (\Haste\Input\Input::getAutoItem('product', false, true) != '') {
         $objProduct = Product::findAvailableByIdOrAlias(\Haste\Input\Input::getAutoItem('product', false, true));
         if (null !== $objProduct) {
             global $objPage;
             global $objIsotopeListPage;
             $last = count($arrItems) - 1;
             // If we have a reader page, rename the last item (the reader) to the product title
             if (null !== $objIsotopeListPage) {
                 $arrItems[$last]['title'] = $this->prepareMetaDescription($objProduct->meta_title ?: $objProduct->name);
                 $arrItems[$last]['link'] = $objProduct->name;
             } else {
                 $arrItems[$last]['href'] = \Controller::generateFrontendUrl($arrItems[$last]['data']);
                 $arrItems[$last]['isActive'] = false;
                 $arrItems[] = array('isRoot' => false, 'isActive' => true, 'href' => $objProduct->generateUrl($objPage), 'title' => $this->prepareMetaDescription($objProduct->meta_title ?: $objProduct->name), 'link' => $objProduct->name, 'data' => $objPage->row());
             }
         }
     }
     return $arrItems;
 }
 protected function getCacheKey()
 {
     return md5('relatedproducts=' . $this->id . ':' . 'product=' . Input::getAutoItem('product', false, true));
 }
Example #11
0
 /**
  * Find product based on InsertTag parameter
  *
  * @param int $id
  *
  * @return IsotopeProduct|null
  */
 private function findCurrentProduct($id = null)
 {
     if (null !== $id) {
         return Product::findAvailableByPk($id);
     } elseif (Product::getActive() !== null) {
         return Product::getActive();
     } else {
         return Product::findAvailableByIdOrAlias(Input::getAutoItem('product', false, true));
     }
 }
Example #12
0
 /**
  * Compile product list.
  *
  * This function is specially designed so you can keep it in your child classes and only override findProducts().
  * You will automatically gain product caching (see class property), grid classes, pagination and more.
  */
 protected function compile()
 {
     // return message if no filter is set
     if ($this->iso_emptyFilter && !\Input::get('isorc') && !\Input::get('keywords')) {
         $this->Template->message = $this->replaceInsertTags($this->iso_noFilter);
         $this->Template->type = 'noFilter';
         $this->Template->products = array();
         return;
     }
     global $objPage;
     $intPage = $this->iso_category_scope == 'article' ? $GLOBALS['ISO_CONFIG']['current_article']['pid'] : $objPage->id;
     $arrProducts = null;
     $arrCacheIds = null;
     // Try to load the products from cache
     if ($this->blnCacheProducts && ($objCache = ProductCache::findForPageAndModule($intPage, $this->id)) !== null) {
         $arrCacheIds = $objCache->getProductIds();
         // Use the cache if keywords match. Otherwise we will use the product IDs as a "limit" for findProducts()
         if ($objCache->keywords == \Input::get('keywords')) {
             $arrCacheIds = $this->generatePagination($arrCacheIds);
             $objProducts = Product::findAvailableByIds($arrCacheIds, array('order' => \Database::getInstance()->findInSet(Product::getTable() . '.id', $arrCacheIds)));
             $arrProducts = null === $objProducts ? array() : $objProducts->getModels();
             // Cache is wrong, drop everything and run findProducts()
             if (count($arrProducts) != count($arrCacheIds)) {
                 $arrCacheIds = null;
                 $arrProducts = null;
             }
         }
     }
     if (!is_array($arrProducts)) {
         // Display "loading products" message and add cache flag
         if ($this->blnCacheProducts) {
             $blnCacheMessage = (bool) $this->iso_productcache[$intPage][(int) \Input::get('isorc')];
             if ($blnCacheMessage && !\Input::get('buildCache')) {
                 // Do not index or cache the page
                 $objPage->noSearch = 1;
                 $objPage->cache = 0;
                 $this->Template = new \Isotope\Template('mod_iso_productlist_caching');
                 $this->Template->message = $GLOBALS['TL_LANG']['MSC']['productcacheLoading'];
                 return;
             }
             // Start measuring how long it takes to load the products
             $start = microtime(true);
             // Load products
             $arrProducts = $this->findProducts($arrCacheIds);
             // Decide if we should show the "caching products" message the next time
             $end = microtime(true) - $start;
             $this->blnCacheProducts = $end > 1 ? true : false;
             $arrCacheMessage = $this->iso_productcache;
             if ($blnCacheMessage != $this->blnCacheProducts) {
                 $arrCacheMessage[$intPage][(int) \Input::get('isorc')] = $this->blnCacheProducts;
                 \Database::getInstance()->prepare("UPDATE tl_module SET iso_productcache=? WHERE id=?")->execute(serialize($arrCacheMessage), $this->id);
             }
             // Do not write cache if table is locked. That's the case if another process is already writing cache
             if (ProductCache::isWritable()) {
                 \Database::getInstance()->lockTables(array(ProductCache::getTable() => 'WRITE', 'tl_iso_product' => 'READ'));
                 $arrIds = array();
                 foreach ($arrProducts as $objProduct) {
                     $arrIds[] = $objProduct->id;
                 }
                 // Delete existing cache if necessary
                 ProductCache::deleteForPageAndModuleOrExpired($intPage, $this->id);
                 $objCache = ProductCache::createForPageAndModule($intPage, $this->id);
                 $objCache->expires = $this->getProductCacheExpiration();
                 $objCache->setProductIds($arrIds);
                 $objCache->save();
                 \Database::getInstance()->unlockTables();
             }
         } else {
             $arrProducts = $this->findProducts();
         }
         if (!empty($arrProducts)) {
             $arrProducts = $this->generatePagination($arrProducts);
         }
     }
     // No products found
     if (!is_array($arrProducts) || empty($arrProducts)) {
         $this->compileEmptyMessage();
         return;
     }
     $arrBuffer = array();
     $arrDefaultOptions = $this->getDefaultProductOptions();
     /** @var \Isotope\Model\Product\Standard $objProduct */
     foreach ($arrProducts as $objProduct) {
         $arrConfig = array('module' => $this, 'template' => $this->iso_list_layout ?: $objProduct->getRelated('type')->list_template, 'gallery' => $this->iso_gallery ?: $objProduct->getRelated('type')->list_gallery, 'buttons' => deserialize($this->iso_buttons, true), 'useQuantity' => $this->iso_use_quantity, 'jumpTo' => $this->findJumpToPage($objProduct));
         if (\Environment::get('isAjaxRequest') && \Input::post('AJAX_MODULE') == $this->id && \Input::post('AJAX_PRODUCT') == $objProduct->getProductId()) {
             $objResponse = new HtmlResponse($objProduct->generate($arrConfig));
             $objResponse->send();
         }
         $objProduct->mergeRow($arrDefaultOptions);
         // Must be done after setting options to generate the variant config into the URL
         if ($this->iso_jump_first && \Haste\Input\Input::getAutoItem('product', false, true) == '') {
             \Controller::redirect($objProduct->generateUrl($arrConfig['jumpTo']));
         }
         $arrCSS = deserialize($objProduct->cssID, true);
         $arrBuffer[] = array('cssID' => $arrCSS[0] != '' ? ' id="' . $arrCSS[0] . '"' : '', 'class' => trim('product ' . ($objProduct->isNew() ? 'new ' : '') . $arrCSS[1]), 'html' => $objProduct->generate($arrConfig), 'product' => $objProduct);
     }
     // HOOK: to add any product field or attribute to mod_iso_productlist template
     if (isset($GLOBALS['ISO_HOOKS']['generateProductList']) && is_array($GLOBALS['ISO_HOOKS']['generateProductList'])) {
         foreach ($GLOBALS['ISO_HOOKS']['generateProductList'] as $callback) {
             $objCallback = \System::importStatic($callback[0]);
             $arrBuffer = $objCallback->{$callback}[1]($arrBuffer, $arrProducts, $this->Template, $this);
         }
     }
     RowClass::withKey('class')->addCount('product_')->addEvenOdd('product_')->addFirstLast('product_')->addGridRows($this->iso_cols)->addGridCols($this->iso_cols)->applyTo($arrBuffer);
     $this->Template->products = $arrBuffer;
 }
 /**
  * The ids of all pages we take care of. This is what should later be used eg. for filter data.
  *
  * @return array
  */
 protected function findCategories()
 {
     if (null === $this->arrCategories) {
         if ($this->defineRoot && $this->rootPage > 0) {
             $objPage = \PageModel::findWithDetails($this->rootPage);
         } else {
             global $objPage;
         }
         $t = \PageModel::getTable();
         $arrCategories = null;
         $arrUnpublished = array();
         $strWhere = "{$t}.type!='error_403' AND {$t}.type!='error_404'";
         if (!BE_USER_LOGGED_IN) {
             $time = time();
             $objUnpublished = \PageModel::findBy(array("({$t}.start!='' AND {$t}.start>{$time}) OR ({$t}.stop!='' AND {$t}.stop<{$time}) OR {$t}.published=?"), array(''));
             $arrUnpublished = $objUnpublished->fetchEach('id');
             //$strWhere .= " AND ($t.start='' OR $t.start<$time) AND ($t.stop='' OR $t.stop>$time) AND $t.published='1'";
         }
         switch ($this->iso_category_scope) {
             case 'global':
                 $arrCategories = array($objPage->rootId);
                 $arrCategories = \Database::getInstance()->getChildRecords($objPage->rootId, 'tl_page', false, $arrCategories, $strWhere);
                 $arrCategories = array_diff($arrCategories, $arrUnpublished);
                 break;
             case 'current_and_first_child':
                 $arrCategories = \Database::getInstance()->execute("SELECT id FROM tl_page WHERE pid={$objPage->id} AND {$strWhere}")->fetchEach('id');
                 $arrCategories[] = $objPage->id;
                 break;
             case 'current_and_all_children':
                 $arrCategories = array($objPage->id);
                 $arrCategories = \Database::getInstance()->getChildRecords($objPage->id, 'tl_page', false, $arrCategories, $strWhere);
                 $arrCategories = array_diff($arrCategories, $arrUnpublished);
                 break;
             case 'parent':
                 $arrCategories = array($objPage->pid);
                 break;
             case 'product':
                 /** @var \Isotope\Model\Product\Standard $objProduct */
                 $objProduct = Product_Model::findAvailableByIdOrAlias(\Haste\Input\Input::getAutoItem('product'));
                 if ($objProduct !== null) {
                     $arrCategories = $objProduct->getCategories(true);
                 } else {
                     $arrCategories = array(0);
                 }
                 break;
             case 'article':
                 $arrCategories = array($GLOBALS['ISO_CONFIG']['current_article']['pid'] ?: $objPage->id);
                 break;
             case '':
             case 'current_category':
                 $arrCategories = array($objPage->id);
                 break;
             default:
                 if (isset($GLOBALS['ISO_HOOKS']['findCategories']) && is_array($GLOBALS['ISO_HOOKS']['findCategories'])) {
                     foreach ($GLOBALS['ISO_HOOKS']['findCategories'] as $callback) {
                         $objCallback = \System::importStatic($callback[0]);
                         $arrCategories = $objCallback->{$callback}[1]($this);
                         if ($arrCategories !== false) {
                             break;
                         }
                     }
                 }
                 break;
         }
         $this->arrCategories = empty($arrCategories) ? array(0) : $arrCategories;
     }
     return $this->arrCategories;
 }