/** * Fill the object's arrProducts array * * @param array|null $arrCacheIds * * @return array */ protected function findProducts($arrCacheIds = null) { $t = Product::getTable(); $arrColumns = array(); $arrCategories = $this->findCategories(); $arrProductIds = \Database::getInstance()->query("\n SELECT pid\n FROM tl_iso_product_category\n WHERE page_id IN (" . implode(',', $arrCategories) . ")\n ")->fetchEach('pid'); $arrTypes = \Database::getInstance()->query("SELECT id FROM tl_iso_producttype WHERE variants='1'")->fetchEach('id'); if (empty($arrProductIds)) { return array(); } $queryBuilder = new FilterQueryBuilder(Isotope::getRequestCache()->getFiltersForModules($this->iso_filterModules)); $arrColumns[] = "(\n ({$t}.id IN (" . implode(',', $arrProductIds) . ") AND {$t}.type NOT IN (" . implode(',', $arrTypes) . "))\n OR {$t}.pid IN (" . implode(',', $arrProductIds) . ")\n )"; if (!empty($arrCacheIds) && is_array($arrCacheIds)) { $arrColumns[] = Product::getTable() . ".id IN (" . implode(',', $arrCacheIds) . ")"; } // Apply new/old product filter if ($this->iso_newFilter == 'show_new') { $arrColumns[] = Product::getTable() . ".dateAdded>=" . Isotope::getConfig()->getNewProductLimit(); } elseif ($this->iso_newFilter == 'show_old') { $arrColumns[] = Product::getTable() . ".dateAdded<" . Isotope::getConfig()->getNewProductLimit(); } if ($this->iso_list_where != '') { $arrColumns[] = $this->iso_list_where; } if ($queryBuilder->hasSqlCondition()) { $arrColumns[] = $queryBuilder->getSqlWhere(); } $arrSorting = Isotope::getRequestCache()->getSortingsForModules($this->iso_filterModules); if (empty($arrSorting) && $this->iso_listingSortField != '') { $direction = $this->iso_listingSortDirection == 'DESC' ? Sort::descending() : Sort::ascending(); $arrSorting[$this->iso_listingSortField] = $direction; } $objProducts = Product::findAvailableBy($arrColumns, $queryBuilder->getSqlValues(), array('order' => 'c.sorting', 'filters' => $queryBuilder->getFilters(), 'sorting' => $arrSorting)); return null === $objProducts ? array() : $objProducts->getModels(); }
/** * Generates the filter */ protected function generateFilter() { $blnShowClear = false; $arrFilters = array(); foreach ($this->iso_filterFields as $strField) { $blnTrail = false; $arrItems = array(); $arrWidget = \Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strField], $strField); // Use the default routine to initialize options data foreach ($arrWidget['options'] as $option) { $varValue = $option['value']; // skip zero values (includeBlankOption) // @deprecated drop "-" when we only have the database table as options source if ($varValue === '' || $varValue === '-') { continue; } $strFilterKey = $strField . '=' . $varValue; $blnActive = Isotope::getRequestCache()->getFilterForModule($strFilterKey, $this->id) !== null; $blnTrail = $blnActive ? true : $blnTrail; $arrItems[] = array('href' => \Haste\Util\Url::addQueryString('cumulativefilter=' . base64_encode($this->id . ';' . ($blnActive ? 'del' : 'add') . ';' . $strField . ';' . $varValue)), 'class' => $blnActive ? 'active' : '', 'title' => specialchars($option['label']), 'link' => $option['label']); } if (!empty($arrItems) || $this->iso_iso_filterHideSingle && count($arrItems) < 2) { $objClass = RowClass::withKey('class')->addFirstLast(); if ($blnTrail) { $objClass->addCustom('sibling'); } $objClass->applyTo($arrItems); $objTemplate = new \Isotope\Template($this->navigationTpl); $objTemplate->level = 'level_2'; $objTemplate->items = $arrItems; $arrFilters[$strField] = array('label' => $arrWidget['label'], 'subitems' => $objTemplate->parse(), 'isActive' => $blnTrail); $blnShowClear = $blnTrail ? true : $blnShowClear; } } $this->Template->filters = $arrFilters; $this->Template->showClear = $blnShowClear; }
/** * @param string $action * @param string $attribute * @param string $value */ private function saveFilter($action, $attribute, $value) { if ($action == 'add') { Isotope::getRequestCache()->setFiltersForModule($this->addFilter($this->activeFilters, $attribute, $value), $this->id); } else { Isotope::getRequestCache()->removeFilterForModule($this->generateFilterKey($attribute, $value), $this->id); } $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, Url::removeQueryString(array('cumulativefilter'), $this->jumpTo ?: null))); }
/** * Generate a filter form */ protected function generateFilters() { $this->Template->hasFilters = false; if (is_array($this->iso_filterFields) && count($this->iso_filterFields)) { $time = time(); $arrFilters = array(); $arrInput = \Input::post('filter'); $arrCategories = $this->findCategories(); foreach ($this->iso_filterFields as $strField) { $arrValues = array(); $objValues = \Database::getInstance()->execute("\n SELECT DISTINCT p1.{$strField} FROM tl_iso_product p1\n LEFT OUTER JOIN tl_iso_product p2 ON p1.pid=p2.id\n WHERE\n p1.language=''\n " . (BE_USER_LOGGED_IN === true ? '' : "AND p1.published='1' AND (p1.start='' OR p1.start<{$time}) AND (p1.stop='' OR p1.stop>{$time}) ") . "\n AND (\n p1.id IN (\n SELECT pid FROM " . \Isotope\Model\ProductCategory::getTable() . " WHERE page_id IN (" . implode(',', $arrCategories) . ")\n )\n OR p1.pid IN (\n SELECT pid FROM " . \Isotope\Model\ProductCategory::getTable() . " WHERE page_id IN (" . implode(',', $arrCategories) . ")\n )\n )\n " . (BE_USER_LOGGED_IN === true ? '' : " AND (p1.pid=0 OR (p2.published='1' AND (p2.start='' OR p2.start<{$time}) AND (p2.stop='' OR p2.stop>{$time})))") . "\n " . ($this->iso_list_where == '' ? '' : " AND " . Haste::getInstance()->call('replaceInsertTags', $this->iso_list_where))); while ($objValues->next()) { $arrValues[] = deserialize($objValues->{$strField}, false); } if ($this->blnUpdateCache && in_array($arrInput[$strField], $arrValues)) { Isotope::getRequestCache()->setFilterForModule($strField, Filter::attribute($strField)->isEqualTo($arrInput[$strField]), $this->id); } elseif ($this->blnUpdateCache && $arrInput[$strField] == '') { Isotope::getRequestCache()->removeFilterForModule($strField, $this->id); } elseif (($objFilter = Isotope::getRequestCache()->getFilterForModule($strField, $this->id)) !== null && $objFilter->valueNotIn($arrValues)) { // Request cache contains wrong value, delete it! $this->blnUpdateCache = true; Isotope::getRequestCache()->removeFilterForModule($strField, $this->id); RequestCache::deleteById(\Input::get('isorc')); } elseif (!$this->blnUpdateCache) { // Only generate options if we do not reload anyway if (empty($arrValues)) { continue; } $arrData = $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strField]; if (is_array($GLOBALS['ISO_ATTR'][$arrData['inputType']]['callback']) && !empty($GLOBALS['ISO_ATTR'][$arrData['inputType']]['callback'])) { foreach ($GLOBALS['ISO_ATTR'][$arrData['inputType']]['callback'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrData = $objCallback->{$callback[1]}($strField, $arrData, $this); } } // Use the default routine to initialize options data $arrWidget = \Widget::getAttributesFromDca($arrData, $strField); $objFilter = Isotope::getRequestCache()->getFilterForModule($strField, $this->id); if (($objAttribute = $GLOBALS['TL_DCA']['tl_iso_product']['attributes'][$strField]) !== null && $objAttribute instanceof IsotopeAttributeWithOptions) { $objAttribute->optionsSource = 'attribute'; $arrWidget['options'] = $objAttribute->getOptionsForProductFilter($arrValues); } foreach ($arrValues as $value) { $arrWidget['options'][] = array('value' => $value, 'label' => $value == '' ? ' ' : 'text'); } // Must have options to apply the filter if (!is_array($arrWidget['options'])) { continue; } foreach ($arrWidget['options'] as $k => $option) { if ($option['value'] == '') { $arrWidget['blankOptionLabel'] = $option['label']; unset($arrWidget['options'][$k]); continue; } elseif (!in_array($option['value'], $arrValues) || $option['value'] == '-') { // @deprecated IsotopeAttributeWithOptions::getOptionsForProductFilter already checks this unset($arrWidget['options'][$k]); continue; } $arrWidget['options'][$k]['default'] = null !== $objFilter && $objFilter->valueEquals($option['value']) ? '1' : ''; } // Hide fields with just one option (if enabled) if ($this->iso_filterHideSingle && count($arrWidget['options']) < 2) { continue; } $arrFilters[$strField] = $arrWidget; } } // !HOOK: alter the filters if (isset($GLOBALS['ISO_HOOKS']['generateFilters']) && is_array($GLOBALS['ISO_HOOKS']['generateFilters'])) { foreach ($GLOBALS['ISO_HOOKS']['generateFilters'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrFilters = $objCallback->{$callback}[1]($arrFilters); } } if (!empty($arrFilters)) { $this->Template->hasFilters = true; $this->Template->filterOptions = $arrFilters; } } }
/** * Get a list of default options based on filter attributes * @return array */ protected function getDefaultProductOptions() { $arrFields = array_merge(Attribute::getVariantOptionFields(), Attribute::getCustomerDefinedFields()); if (empty($arrFields)) { return array(); } $arrOptions = array(); $arrFilters = Isotope::getRequestCache()->getFiltersForModules($this->iso_filterModules); foreach ($arrFilters as $arrConfig) { if (in_array($arrConfig['attribute'], $arrFields) && ($arrConfig['operator'] == '=' || $arrConfig['operator'] == '==' || $arrConfig['operator'] == 'eq')) { $arrOptions[$arrConfig['attribute']] = $arrConfig['value']; } } return $arrOptions; }
/** * Generate a limit form */ protected function generateLimit() { $this->Template->hasLimit = false; if ($this->iso_enableLimit) { $arrOptions = array(); $arrLimit = array_map('intval', trimsplit(',', $this->iso_perPage)); $objLimit = Isotope::getRequestCache()->getFirstLimitForModules(array($this->id)); $arrLimit = array_unique($arrLimit); sort($arrLimit); if ($this->blnUpdateCache && in_array(\Input::post('limit'), $arrLimit)) { // Cache new request value Isotope::getRequestCache()->setLimitForModule(Limit::to(\Input::post('limit')), $this->id); } elseif ($objLimit->notIn($arrLimit)) { // Request cache contains wrong value, delete it! $this->blnUpdateCache = true; Isotope::getRequestCache()->setLimitForModule(Limit::to($arrLimit[0]), $this->id); RequestCache::deleteById(\Input::get('isorc')); } elseif (!$this->blnUpdateCache) { // No need to generate options if we reload anyway foreach ($arrLimit as $limit) { $arrOptions[] = array('label' => $limit, 'value' => $limit, 'default' => $objLimit->equals($limit) ? '1' : ''); } $this->Template->hasLimit = true; $this->Template->limitLabel = $GLOBALS['TL_LANG']['MSC']['perPageLabel']; $this->Template->limitOptions = $arrOptions; } } }
/** * Get a list of default options based on filter attributes * @return array */ protected function getDefaultProductOptions() { $arrOptions = array(); $arrFilters = Isotope::getRequestCache()->getFiltersForModules($this->iso_filterModules); foreach ($arrFilters as $arrConfig) { if ($arrConfig['operator'] == '=' || $arrConfig['operator'] == '==' || $arrConfig['operator'] == 'eq') { $arrOptions[$arrConfig['attribute']] = $arrConfig['value']; } } return $arrOptions; }