* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler; /** * @internal */ class Configuration { /** * @var int[] */ private $thresholds; /** * @var string */ private $regex; /** * @var bool */ private $enabled = true; /** * @var bool */ private $verboseOutput = true; /** * @param int[] $thresholds A hash associating groups to thresholds * @param string $regex Will be matched against messages, to decide * whether to display a stack trace * @param bool $verboseOutput */ private function __construct(array $thresholds = [], $regex = '', $verboseOutput = true) { $groups = ['total', 'indirect', 'direct', 'self']; foreach ($thresholds as $group => $threshold) { if (!\in_array($group, $groups, true)) { throw new \InvalidArgumentException(sprintf('Unrecognized threshold "%s", expected one of "%s"', $group, implode('", "', $groups))); } if (!is_numeric($threshold)) { throw new \InvalidArgumentException(sprintf('Threshold for group "%s" has invalid value "%s"', $group, $threshold)); } $this->thresholds[$group] = (int) $threshold; } if (isset($this->thresholds['direct'])) { $this->thresholds += [ 'self' => $this->thresholds['direct'], ]; } if (isset($this->thresholds['indirect'])) { $this->thresholds += [ 'direct' => $this->thresholds['indirect'], 'self' => $this->thresholds['indirect'], ]; } foreach ($groups as $group) { if (!isset($this->thresholds[$group])) { $this->thresholds[$group] = 999999; } } $this->regex = $regex; $this->verboseOutput = $verboseOutput; } /** * @return bool */ public function isEnabled() { return $this->enabled; } /** * @param mixed[] $deprecations * * @return bool */ public function tolerates(array $deprecations) { $deprecationCounts = []; foreach ($deprecations as $key => $deprecation) { if (false !== strpos($key, 'Count') && false === strpos($key, 'legacy')) { $deprecationCounts[$key] = $deprecation; } } if (array_sum($deprecationCounts) > $this->thresholds['total']) { return false; } foreach (['self', 'direct', 'indirect'] as $deprecationType) { if ($deprecationCounts['remaining '.$deprecationType.'Count'] > $this->thresholds[$deprecationType]) { return false; } } return true; } /** * @param string $message * * @return bool */ public function shouldDisplayStackTrace($message) { return '' !== $this->regex && preg_match($this->regex, $message); } /** * @return bool */ public function isInRegexMode() { return '' !== $this->regex; } /** * @return bool */ public function verboseOutput() { return $this->verboseOutput; } /** * @param string $serializedConfiguration an encoded string, for instance * max[total]=1234&max[indirect]=42 * * @return self */ public static function fromUrlEncodedString($serializedConfiguration) { parse_str($serializedConfiguration, $normalizedConfiguration); foreach (array_keys($normalizedConfiguration) as $key) { if (!\in_array($key, ['max', 'disabled', 'verbose'], true)) { throw new \InvalidArgumentException(sprintf('Unknown configuration option "%s"', $key)); } } if (isset($normalizedConfiguration['disabled'])) { return self::inDisabledMode(); } $verboseOutput = true; if (isset($normalizedConfiguration['verbose'])) { $verboseOutput = (bool) $normalizedConfiguration['verbose']; } return new self( isset($normalizedConfiguration['max']) ? $normalizedConfiguration['max'] : [], '', $verboseOutput ); } /** * @return self */ public static function inDisabledMode() { $configuration = new self(); $configuration->enabled = false; return $configuration; } /** * @return self */ public static function inStrictMode() { return new self(['total' => 0]); } /** * @return self */ public static function inWeakMode() { return new self([], '', false); } /** * @return self */ public static function fromNumber($upperBound) { return new self(['total' => $upperBound]); } /** * @return self */ public static function fromRegex($regex) { return new self([], $regex); } }