/** * Drops all related to index database structures. * * @param integer $iblockId Information block identifier. * * @return void * @throws \Bitrix\Main\Db\SqlQueryException */ public static function dropIfExists($iblockId) { $storage = new Storage($iblockId); if ($storage->isExists()) { $storage->drop(); } $dictionary = new Dictionary($iblockId); if ($dictionary->isExists()) { $dictionary->drop(); } }
/** * Returns all relevant information for the element in section context. * * @param Element $element Loaded from the database element information. * * @return array */ protected function getSectionIndexEntries(Element $element) { $result = array(1 => array(array("VALUE" => 0, "VALUE_NUM" => 0.0))); foreach ($this->getFilterProperty(Storage::DICTIONARY) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { $value = intval($value); $result[$facetId][$value] = array("VALUE" => $value, "VALUE_NUM" => 0.0); } } foreach ($this->getFilterProperty(Storage::STRING) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { $valueId = $this->dictionary->getStringId($value); $result[$facetId][$valueId] = array("VALUE" => $valueId, "VALUE_NUM" => 0.0); } } foreach ($this->getFilterProperty(Storage::NUMERIC) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { $value = doubleval($value); $result[$facetId][md5($value)] = array("VALUE" => 0, "VALUE_NUM" => $value); } } foreach ($this->getFilterProperty(Storage::DATETIME) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { //Save date only based on server time. $timestamp = MakeTimeStamp($value, "YYYY-MM-DD HH:MI:SS"); $value = date('Y-m-d', $timestamp); $timestamp = MakeTimeStamp($value, "YYYY-MM-DD"); $valueId = $this->dictionary->getStringId($value); $result[$facetId][$valueId] = array("VALUE" => $valueId, "VALUE_NUM" => $timestamp); } } foreach ($this->getFilterPrices() as $priceId) { $facetId = $this->storage->priceIdToFacetId($priceId); $result[$facetId] = array(); $elementPrices = $element->getPriceValues($priceId); if ($elementPrices) { foreach ($elementPrices as $currency => $priceValues) { $currencyId = $this->dictionary->getStringId($currency); foreach ($priceValues as $price) { $result[$facetId][$currencyId . ":" . $price] = array("VALUE" => $currencyId, "VALUE_NUM" => $price); } } } } return array_filter($result, "count"); }
/** * Adds a condition for further filtering. * * @param integer $propertyId Iblock property identifier. * @param string $operator Comparing operator. * @param float $value Value to compare. * * @return void */ public function addDictionaryPropertyFilter($propertyId, $operator, $value) { $facetId = $this->storage->propertyIdToFacetId($propertyId); if ($operator == "=") { if (isset($this->where[$facetId])) { $this->where[$facetId]["VALUES"][] = intval($value); } else { $this->where[$facetId] = array("TYPE" => Storage::DICTIONARY, "OP" => $operator, "FACET_ID" => $facetId, "VALUES" => array(intval($value))); } } }
/** * Returns all relevant information for the element in section context. * * @param Element $element Loaded from the database element information. * @param integer $sectionId Section identifier. * * @return array */ protected function getSectionIndexEntries(Element $element, $sectionId) { $result = array(1 => array(array("VALUE" => 0, "VALUE_NUM" => 0.0))); foreach ($this->getFilterProperty(Storage::DICTIONARY) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { $value = intval($value); $result[$facetId][$value] = array("VALUE" => $value, "VALUE_NUM" => 0.0); } } foreach ($this->getFilterProperty(Storage::STRING) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { $valueId = $this->dictionary->getStringId($value); $result[$facetId][$valueId] = array("VALUE" => $valueId, "VALUE_NUM" => 0.0); } } foreach ($this->getFilterProperty(Storage::NUMERIC) as $propertyId) { $facetId = $this->storage->propertyIdToFacetId($propertyId); $result[$facetId] = array(); $propertyValues = $element->getPropertyValues($propertyId); foreach ($propertyValues as $value) { $value = doubleval($value); $result[$facetId][md5($value)] = array("VALUE" => 0, "VALUE_NUM" => $value); } } foreach ($this->getFilterPrices($sectionId) as $priceId) { $facetId = $this->storage->priceIdToFacetId($priceId); $result[$facetId] = array(); $elementPrices = $element->getPriceValues($priceId); if ($elementPrices) { foreach ($elementPrices as $currency => $priceValues) { $currencyId = $this->dictionary->getStringId($currency); foreach ($priceValues as $price) { $result[$facetId][$currencyId . ":" . $price] = array("VALUE" => $currencyId, "VALUE_NUM" => $price); } } } } return array_filter($result, "count"); }
/** * Adds a condition for further filtering. * * @param integer $propertyId Iblock property identifier. * @param string $operator Comparing operator. * @param float $value Timestamp to compare. * * @return void */ public function addDatetimePropertyFilter($propertyId, $operator, $value) { $facetId = $this->storage->propertyIdToFacetId($propertyId); if ($operator == "<=" || $operator == ">=") { $this->where[$operator . $facetId] = array("TYPE" => Storage::DATETIME, "OP" => $operator, "FACET_ID" => $facetId, "VALUES" => array(intval($value))); if (isset($this->where[">=" . $facetId]) && isset($this->where["<=" . $facetId])) { $this->where["><" . $facetId] = array("TYPE" => Storage::DATETIME, "OP" => "><", "FACET_ID" => $facetId, "VALUES" => array($this->where[">=" . $facetId]["VALUES"][0], $this->where["<=" . $facetId]["VALUES"][0])); unset($this->where[">=" . $facetId]); unset($this->where["<=" . $facetId]); } } elseif ($operator == "=") { if (isset($this->where[$operator . $facetId])) { $this->where[$operator . $facetId]["VALUES"][] = intval($value); } else { $this->where[$operator . $facetId] = array("TYPE" => Storage::DATETIME, "OP" => $operator, "FACET_ID" => $facetId, "VALUES" => array(intval($value))); } } }
$facetId = $row["FACET_ID"]; if (\Bitrix\Iblock\PropertyIndex\Storage::isPropertyId($facetId)) { $pp = \Bitrix\Iblock\PropertyIndex\Storage::facetIdToPropertyId($facetId); if ($arResult["ITEMS"][$pp]["PROPERTY_TYPE"] == "N") { if (is_array($arResult["ITEMS"][$pp]["VALUES"])) { $arResult["ITEMS"][$pp]["VALUES"]["MIN"]["FILTERED_VALUE"] = $row["MIN_VALUE_NUM"]; $arResult["ITEMS"][$pp]["VALUES"]["MAX"]["FILTERED_VALUE"] = $row["MAX_VALUE_NUM"]; } } else { if (isset($facetIndex[$pp][$row["VALUE"]])) { unset($facetIndex[$pp][$row["VALUE"]]["DISABLED"]); $facetIndex[$pp][$row["VALUE"]]["ELEMENT_COUNT"] = $row["ELEMENT_COUNT"]; } } } else { $priceId = \Bitrix\Iblock\PropertyIndex\Storage::facetIdToPriceId($facetId); foreach ($arResult["PRICES"] as $NAME => $arPrice) { if ($arPrice["ID"] == $priceId && isset($arResult["ITEMS"][$NAME]) && is_array($arResult["ITEMS"][$NAME]["VALUES"])) { $arResult["ITEMS"][$NAME]["VALUES"]["MIN"]["FILTERED_VALUE"] = $row["MIN_VALUE_NUM"]; $arResult["ITEMS"][$NAME]["VALUES"]["MAX"]["FILTERED_VALUE"] = $row["MAX_VALUE_NUM"]; } } } } } } else { $index = array(); foreach ($arResult["COMBO"] as $id => $combination) { foreach ($combination as $PID => $value) { $index[$PID][$value][] =& $arResult["COMBO"][$id]; }
/** * Goes through the $filter and creates unified conditions in $where array. * * @param array &$where Output result. * @param boolean &$hasAdditionalFilters Whenever has some filters left or not. * @param array &$toUnset Output $filter keys which may be excluded. * @param array &$filter Filter to go through. * * @return void */ private function fillWhere(&$where, &$hasAdditionalFilters, &$toUnset, &$filter) { $properties = $this->getFilterProperty(); foreach ($filter as $filterKey => $filterValue) { if (preg_match("/^(=)PROPERTY\$/i", $filterKey, $keyDetails) && is_array($filterValue)) { foreach ($filterValue as $propertyId => $value) { $facetId = $this->storage->propertyIdToFacetId($propertyId); if ($properties[$propertyId] == Storage::DICTIONARY || $properties[$propertyId] == Storage::STRING) { $sqlValues = $this->getInSql($value, $properties[$propertyId] == Storage::STRING); if ($sqlValues) { $where[] = array("TYPE" => $properties[$propertyId], "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => $sqlValues); $toUnset[] = array(&$filter[$filterKey], $propertyId); } } } } elseif (preg_match("/^(=)PROPERTY_(\\d+)\$/i", $filterKey, $keyDetails)) { $propertyId = $keyDetails[2]; $value = $filterValue; $facetId = $this->storage->propertyIdToFacetId($propertyId); if ($properties[$propertyId] == Storage::DICTIONARY || $properties[$propertyId] == Storage::STRING) { $sqlValues = $this->getInSql($value, $properties[$propertyId] == Storage::STRING); if ($sqlValues) { $where[] = array("TYPE" => $properties[$propertyId], "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => $sqlValues); $toUnset[] = array(&$filter, $filterKey); } } } elseif (preg_match("/^(>=|<=)PROPERTY\$/i", $filterKey, $keyDetails) && is_array($filterValue)) { foreach ($filterValue as $propertyId => $value) { $facetId = $this->storage->propertyIdToFacetId($propertyId); if ($properties[$propertyId] == Storage::NUMERIC) { if (is_array($value)) { $doubleValue = doubleval(current($value)); } else { $doubleValue = doubleval($value); } $where[] = array("TYPE" => Storage::NUMERIC, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($doubleValue)); $toUnset[] = array(&$filter[$filterKey], $propertyId); } elseif ($properties[$propertyId] == Storage::DATETIME) { if (is_array($value)) { $timestamp = MakeTimeStamp(current($value), "YYYY-MM-DD HH:MI:SS"); } else { $timestamp = MakeTimeStamp($value, "YYYY-MM-DD HH:MI:SS"); } $where[] = array("TYPE" => Storage::DATETIME, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($timestamp)); $toUnset[] = array(&$filter[$filterKey], $propertyId); } } } elseif (preg_match("/^(><)PROPERTY\$/i", $filterKey, $keyDetails) && is_array($filterValue)) { foreach ($filterValue as $propertyId => $value) { $facetId = $this->storage->propertyIdToFacetId($propertyId); if ($properties[$propertyId] == Storage::NUMERIC) { if (is_array($value) && count($value) == 2) { $doubleMinValue = doubleval(current($value)); $doubleMaxValue = doubleval(end($value)); $where[] = array("TYPE" => Storage::NUMERIC, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($doubleMinValue, $doubleMaxValue)); $toUnset[] = array(&$filter[$filterKey], $propertyId); } } elseif ($properties[$propertyId] == Storage::DATETIME) { if (is_array($value) && count($value) == 2) { $timestamp1 = MakeTimeStamp(current($value), "YYYY-MM-DD HH:MI:SS"); $timestamp2 = MakeTimeStamp(end($value), "YYYY-MM-DD HH:MI:SS"); $where[] = array("TYPE" => Storage::DATETIME, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($timestamp1, $timestamp2)); $toUnset[] = array(&$filter[$filterKey], $propertyId); } } } } elseif ($this->options["PRICE_FILTER"] && preg_match("/^(>=|<=)CATALOG_PRICE_(\\d+)\$/i", $filterKey, $keyDetails) && !is_array($filterValue)) { $priceId = $keyDetails[2]; $value = $filterValue; $facetId = $this->storage->priceIdToFacetId($priceId); $doubleValue = doubleval($value); $where[] = array("TYPE" => Storage::PRICE, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($doubleValue)); $toUnset[] = array(&$filter, $filterKey); } elseif ($this->options["PRICE_FILTER"] && preg_match("/^(><)CATALOG_PRICE_(\\d+)\$/i", $filterKey, $keyDetails) && is_array($filterValue)) { $priceId = $keyDetails[2]; $value = $filterValue; $facetId = $this->storage->priceIdToFacetId($priceId); $doubleValueMin = doubleval($value[0]); $doubleValueMax = doubleval($value[1]); $where[] = array("TYPE" => Storage::PRICE, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($doubleValueMin, $doubleValueMax)); $toUnset[] = array(&$filter, $filterKey); } elseif ($this->options["PRICE_FILTER"] && is_numeric($filterKey) && is_array($filterValue) && count($filterValue) === 3 && isset($filterValue["LOGIC"]) && $filterValue["LOGIC"] === "OR" && isset($filterValue["=ID"]) && is_object($filterValue["=ID"]) && preg_match("/^(>=|<=)CATALOG_PRICE_(\\d+)\$/i", key($filterValue[0][0]), $keyDetails) && !is_array(current($filterValue[0][0]))) { $priceId = $keyDetails[2]; $value = current($filterValue[0][0]); $facetId = $this->storage->priceIdToFacetId($priceId); $doubleValue = doubleval($value); $where[] = array("TYPE" => Storage::PRICE, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($doubleValue)); $toUnset[] = array(&$filter, $filterKey); $toUnset[] = array(&$filter, "CATALOG_SHOP_QUANTITY_1"); } elseif ($this->options["PRICE_FILTER"] && is_numeric($filterKey) && is_array($filterValue) && count($filterValue) === 3 && isset($filterValue["LOGIC"]) && $filterValue["LOGIC"] === "OR" && isset($filterValue["=ID"]) && is_object($filterValue["=ID"]) && preg_match("/^(><)CATALOG_PRICE_(\\d+)\$/i", key($filterValue[0][0]), $keyDetails) && is_array(current($filterValue[0][0]))) { $priceId = $keyDetails[2]; $value = current($filterValue[0][0]); $facetId = $this->storage->priceIdToFacetId($priceId); $doubleValueMin = doubleval($value[0]); $doubleValueMax = doubleval($value[1]); $where[] = array("TYPE" => Storage::PRICE, "OP" => $keyDetails[1], "FACET_ID" => $facetId, "VALUES" => array($doubleValueMin, $doubleValueMax)); $toUnset[] = array(&$filter, $filterKey); $toUnset[] = array(&$filter, "CATALOG_SHOP_QUANTITY_1"); } elseif ($filterKey !== "IBLOCK_ID" && $filterKey !== "ACTIVE" && $filterKey !== "ACTIVE_DATE") { $hasAdditionalFilters = true; } } }