private function removeDuplicatesInValuesBag(FieldConfigInterface $config, ValuesBag $valuesBag) { $comparison = $config->getValueComparison(); $options = $config->getOptions(); $this->removeDuplicateValues($valuesBag->getSimpleValues(), $valuesBag, $comparison, $options); $this->removeDuplicateValues($valuesBag->getExcludedSimpleValues(), $valuesBag, $comparison, $options, true); $this->removeDuplicateRanges($valuesBag->get(Range::class), $valuesBag, $comparison, $options); $this->removeDuplicateRanges($valuesBag->get(ExcludedRange::class), $valuesBag, $comparison, $options, true); $this->removeDuplicateComparisons($valuesBag, $comparison, $options); $this->removeDuplicateMatchers($valuesBag, $comparison, $options); }
/** * @param FieldConfigInterface $config * @param ValuesBag $valuesBag */ private function normalizeRangesInValuesBag(FieldConfigInterface $config, ValuesBag $valuesBag) { $comparison = $config->getValueComparison(); $options = $config->getOptions(); // Optimize the ranges before simple values, so we have less ranges to loop trough. // Each operation is run separate to reduce complexity and prevent hard to find bugs, // this results in less performance but better readability; // Results should be cached anyway. if ($valuesBag->has(Range::class)) { $this->removeOverlappingRanges($valuesBag->get(Range::class), $valuesBag, $comparison, $options); $this->optimizeConnectedRanges($valuesBag->get(Range::class), $valuesBag, $comparison, $options); $this->removeOverlappingSingleValues($valuesBag->getSimpleValues(), $valuesBag->get(Range::class), $valuesBag, $comparison, $options); } if ($valuesBag->has(ExcludedRange::class)) { $this->removeOverlappingRanges($valuesBag->get(ExcludedRange::class), $valuesBag, $comparison, $options); $this->optimizeConnectedRanges($valuesBag->get(ExcludedRange::class), $valuesBag, $comparison, $options, true); $this->removeOverlappingSingleValues($valuesBag->getExcludedSimpleValues(), $valuesBag->get(ExcludedRange::class), $valuesBag, $comparison, $options, true); } }
/** * 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); } } } }