• Модуль: iblock
  • Путь к файлу: ~/bitrix/modules/iblock/lib/propertyindex/querybuilder.php
  • Класс: BitrixIblockPropertyIndexQueryBuilder
  • Вызов: QueryBuilder::fillWhere
private function fillWhere(&$where, &$hasAdditionalFilters, &$toUnset, &$filter)
{
	$countUnset = count($toUnset);
	$properties = null;
	$propertyCodeMap = null;

	$usePriceFilter = isset($this->options['PRICE_FILTER']) && $this->options['PRICE_FILTER'];

	foreach ($filter as $filterKey => $filterValue)
	{
		if (preg_match("/^(=)PROPERTY$/i", $filterKey, $keyDetails) && is_array($filterValue))
		{
			if ($properties === null)
				$properties = $this->getFilterProperty();
			if ($propertyCodeMap === null)
			{
				$propertyCodeMap = $this->getPropertyCodeMap();
			}

			foreach ($filterValue as $propertyId => $value)
			{
				$propertyId = $propertyCodeMap[$propertyId] ?? null;
				if (
					$propertyId === null
					|| !isset($properties[$propertyId])
				)
				{
					continue;
				}
				$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))
		{
			if ($properties === null)
				$properties = $this->getFilterProperty();
			if ($propertyCodeMap === null)
			{
				$propertyCodeMap = $this->getPropertyCodeMap();
			}

			$propertyId = $propertyCodeMap[$keyDetails[2]] ?? null;
			if (
				$propertyId === null
				|| !isset($properties[$propertyId])
			)
			{
				continue;
			}
			$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))
		{
			if ($properties === null)
				$properties = $this->getFilterProperty();
			if ($propertyCodeMap === null)
			{
				$propertyCodeMap = $this->getPropertyCodeMap();
			}

			foreach ($filterValue as $propertyId => $value)
			{
				$propertyId = $propertyCodeMap[$propertyId] ?? null;
				if (
					$propertyId === null
					|| !isset($properties[$propertyId])
				)
				{
					continue;
				}
				$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))
		{
			if ($properties === null)
				$properties = $this->getFilterProperty();
			if ($propertyCodeMap === null)
			{
				$propertyCodeMap = $this->getPropertyCodeMap();
			}

			foreach ($filterValue as $propertyId => $value)
			{
				$propertyId = $propertyCodeMap[$propertyId] ?? null;
				if (
					$propertyId === null
					|| !isset($properties[$propertyId])
				)
				{
					continue;
				}
				$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 (
			$usePriceFilter
			&& 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 (
			$usePriceFilter
			&& 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 (
			$usePriceFilter
			&& 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_".$priceId);
		}
		elseif (
			$usePriceFilter
			&& 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_".$priceId);
		}
		elseif (
			$filterKey !== "IBLOCK_ID"
			&& $filterKey !== "ACTIVE"
			&& $filterKey !== "ACTIVE_DATE"
		)
		{
			$hasAdditionalFilters = true;
		}
	}
	if ($hasAdditionalFilters)
	{
		while (count($toUnset) > $countUnset)
		{
			array_pop($toUnset);
		}
	}
}