예제 #1
0
 /**
  * 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();
     }
 }
예제 #2
0
 /**
  * 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");
 }
예제 #3
0
 /**
  * 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)));
         }
     }
 }
예제 #4
0
 /**
  * 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");
 }
예제 #5
0
 /**
  * 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)));
         }
     }
 }
예제 #6
0
             $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];
         }
예제 #7
0
 /**
  * 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;
         }
     }
 }