/** * Optimizes connected ranges. * * A range is connected when the upper-bound is equal to the lower-bound of the * second range, but only when the bounds inclusiveness are equal they can be optimized. * * @param Range[] $ranges * @param ValuesBag $valuesBag * @param ValueComparisonInterface $comparison * @param array $options */ private function optimizeConnectedRanges(array $ranges, ValuesBag $valuesBag, ValueComparisonInterface $comparison, array $options, $exclude = false) { $class = $exclude ? ExcludedRange::class : Range::class; foreach ($ranges as $i => $range) { // If the range is already removed just ignore it. if (!isset($ranges[$i])) { continue; } foreach ($ranges as $c => $value) { if ($i === $c) { continue; } if ($range->isLowerInclusive() !== $value->isLowerInclusive() || $range->isUpperInclusive() !== $value->isUpperInclusive()) { continue; } if ($comparison->isEqual($range->getUpper(), $value->getLower(), $options)) { $newRange = new $class($range->getLower(), $value->getUpper(), $range->isLowerInclusive(), $range->isUpperInclusive(), $range->getViewLower(), $value->getViewUpper()); $valuesBag->remove($class, $i); $valuesBag->remove($class, $c); $valuesBag->add($newRange); unset($ranges[$i], $ranges[$c]); } } } }
/** * Converts a list of values to ranges. * * @param array $values * @param ValuesBag $valuesBag * @param FieldConfigInterface $config * @param bool $exclude */ private function listToRanges($values, ValuesBag $valuesBag, FieldConfigInterface $config, $exclude = false) { $class = $exclude ? ExcludedRange::class : Range::class; /** @var ValueIncrementerInterface $comparison */ $comparison = $config->getValueComparison(); $options = $config->getOptions(); $prevIndex = null; $prevValue = null; $rangeLower = null; $rangeUpper = null; $valuesCount = count($values); $curCount = 0; foreach ($values as $valIndex => $value) { ++$curCount; if (null === $prevValue) { $prevIndex = $valIndex; $prevValue = $value; continue; } $unsetIndex = null; $increasedValue = $comparison->getIncrementedValue($prevValue, $options); if ($comparison->isEqual($value, $increasedValue, $options)) { if (null === $rangeLower) { $rangeLower = $prevValue; } $rangeUpper = $value; } if (null !== $rangeUpper) { $unsetIndex = $prevIndex; if ($curCount === $valuesCount || !$comparison->isEqual($value, $increasedValue, $options)) { $range = new $class($rangeLower, $rangeUpper, true, true); $valuesBag->add($range); $unsetIndex = $prevIndex; if ($curCount === $valuesCount) { $unsetIndex = $valIndex; } $rangeLower = $rangeUpper = null; } $prevIndex = $valIndex; $prevValue = $value; } if (null !== $unsetIndex) { if ($exclude) { $valuesBag->removeExcludedSimpleValue($unsetIndex); } else { $valuesBag->removeSimpleValue($unsetIndex); } } } }