8000 clarified exception message to show the actual type passed to the res… · symfony/symfony@0de9a59 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0de9a59

Browse files
author
Cas Leentfaar
committed
clarified exception message to show the actual type passed to the resolver
further improved message of the exception
1 parent e19680f commit 0de9a59

File tree

1 file changed

+145
-18
lines changed
< 8000 /div>

1 file changed

+145
-18
lines changed

src/Symfony/Component/OptionsResolver/Options.php

Lines changed: 145 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,45 @@
2323
*/
2424
class Options implements \ArrayAccess, \Iterator, \Countable
2525
{
26+
/**
27+
* Whether to format {@link \DateTime} objects as RFC-3339 dates
28+
* during exceptions ("Y-m-d H:i:s").
29+
*
30+
* @var int
31+
*/
32+
const PRETTY_DATE = 1;
33+
34+
/**
35+
* Whether to cast objects with a "__toString()" method to strings during exceptions.
36+
*
37+
* @var int
38+
*/
39+
const OBJECT_TO_STRING = 2;
40+
2641
/**
2742
* A list of option values.
43+
*
2844
* @var array
2945
*/
3046
private $options = array();
3147

3248
/**
3349
* A list of normalizer closures.
50+
*
3451
* @var array
3552
*/
3653
private $normalizers = array();
3754

3855
/**
3956
* A list of closures for evaluating lazy options.
57+
*
4058
* @var array
4159
*/
4260
private $lazy = array();
4361

4462
/**
4563
* A list containing the currently locked options.
64+
*
4665
* @var array
4766
*/
4867
private $lock = array();
@@ -228,7 +247,7 @@ public static function validateTypes(array $options, array $acceptedTypes)
228247
continue;
229248
}
230249

231-
$value = $options[$option];
250+
$value = $options[$option];
232251
$optionTypes = (array) $optionTypes;
233252

234253
foreach ($optionTypes as $type) {
@@ -241,17 +260,11 @@ public static function validateTypes(array $options, array $acceptedTypes)
241260
}
242261
}
243262

244-
$printableValue = is_object($value)
245-
? get_class($value)
246-
: (is_array($value)
247-
? 'Array'
248-
: (string) $value);
249-
250263
throw new InvalidOptionsException(sprintf(
251264
'The option "%s" with value "%s" is expected to be of type "%s"',
252265
$option,
253-
$printableValue,
254-
implode('", "', $optionTypes)
266+
self::formatValue($value),
267+
implode('", "', self::formatTypesOf($optionTypes))
255268
));
256269
}
257270
}
@@ -275,7 +288,7 @@ public static function validateValues(array $options, array $acceptedValues)
275288
foreach ($acceptedValues as $option => $optionValues) {
276289
if (array_key_exists($option, $options)) {
277290
if (is_array($optionValues) && !in_array($options[$option], $optionValues, true)) {
278-
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", but is expected to be one of "%s"', $option, $options[$option], implode('", "', $optionValues)));
291+
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", but is expected to be one of "%s"', $option, $options[$option], implode('", "', self::formatValues($optionValues))));
279292
}
280293

281294
if (is_callable($optionValues) && !call_user_func($optionValues, $options[$option])) {
@@ -285,6 +298,120 @@ public static function validateValues(array $options, array $acceptedValues)
285298
}
286299
}
287300

301+
/**
302+
* Returns a string representation of the type of the value.
303+
*
304+
* @param mixed $value
305+
*
306+
* @return string
307+
*/
308+
private static function formatTypeOf($value)
309+
{
310+
return is_object($value) ? get_class($value) : gettype($value);
311+
}
312+
313+
/**
314+
* @param array $optionTypes
315+
*
316+
* @return array
317+
*/
318+
private static function formatTypesOf(array $optionTypes)
319+
{
320+
foreach ($optionTypes as $x => $type) {
321+
$optionTypes[$x] = self::formatTypeOf($type);
322+
}
323+
324+
return $optionTypes;
325+
}
326+
327+
/**
328+
* Returns a string representation of the value.
329+
*
330+
* This method returns the equivalent PHP tokens for most scalar types
331+
* (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped
332+
* in double quotes ("). Objects, arrays and resources are formatted as
333+
* "object", "array" and "resource". If the parameter $prettyDateTime
334+
* is set to true, {@link \DateTime} objects will be formatted as
335+
* RFC-3339 dates ("Y-m-d H:i:s").
336+
*
337+
* @param mixed $value The value to format as string
338+
* @param int $format A bitwise combination of the format
339+
* constants in this class
340+
*
341+
* @return string The string representation of the passed value
342+
*/
343+
private static function formatValue($value, $format = 0)
344+
{
345+
$isDateTime = $value instanceof \DateTime || $value instanceof \DateTimeInterface;
346+
if (($format & self::PRETTY_DATE) && $isDateTime) {
347+
if (class_exists('IntlDateFormatter')) {
348+
$locale = \Locale::getDefault();
349+
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
350+
// neither the native nor the stub IntlDateFormatter support
351+
// DateTimeImmutable as of yet
352+
if (!$value instanceof \DateTime) {
353+
$value = new \DateTime(
354+
$value->format('Y-m-d H:i:s.u e'),
355+
$value->getTimezone()
356+
);
357+
}
358+
359+
return $formatter->format($value);
360+
}
361+
362+
return $value->format('Y-m-d H:i:s');
363+
}
364+
365+
if (is_object($value)) {
366+
if ($format & self::OBJECT_TO_STRING && method_exists($value, '__toString')) {
367+
return $value->__toString();
368+
}
369+
370+
return 'object';
371+
}
372+
373+
if (is_array($value)) {
374+
return 'array';
375+
}
376+
377+
if (is_string($value)) {
378+
return '"'.$value.'"';
379+
}
380+
381+
if (is_resource($value)) {
382+
return 'resource';
383+
}
384+
385+
if (null === $value) {
386+
return 'null';
387+
}
388+
389+
if (false === $value) {
390+
return 'false';
391+
}
392+
393+
if (true === $value) {
394+
return 'true';
395+
}
396+
397+
return (string) $value;
398+
}
399+
400+
/**
401+
* Returns a string representation of a list of values.
402+
*
403+
* @param array $values
404+
* @param bool $prettyDateTime
405+
*
406+
* @return string
407+
*/
408+
private static function formatValues(array $values, $prettyDateTime = false)
409+
{
410+
return array_map(function ($value) use ($prettyDateTime) {
411+
return self::formatValue($value, $prettyDateTime);
412+
}, $values);
413+
}
414+
288415
/**
289416
* Constructs a new object with a set of default options.
290417
*
@@ -382,8 +509,8 @@ public function replace(array $options)
382509
throw new OptionDefinitionException('Options cannot be replaced anymore once options have been read.');
383510
}
384511

385-
$this->options = array();
386-
$this->lazy = array();
512+
$this->options = array();
513+
$this->lazy = array();
387514
$this->normalizers = array();
388515

389516
foreach ($options as $option => $value) {
@@ -424,7 +551,7 @@ public function overload($option, $value)
424551
$reflClosure = is_array($value)
425552
? new \ReflectionMethod($value[0], $value[1])
426553
: new \ReflectionFunction($value);
427-
$params = $reflClosure->getParameters();
554+
$params = $reflClosure->getParameters();
428555

429556
if (isset($params[0]) && null !== ($class = $params[0]->getClass()) && __CLASS__ === $class->name) {
430557
// Initialize the option if no previous value exists
@@ -487,7 +614,7 @@ public function get($option)
487614
*
488615
* @param string $option The option name.
489616
*
490-
* @return bool Whether the option exists.
617+
* @return bool Whether the option exists.
491618
*/
492619
public function has($option)
493620
{
@@ -527,8 +654,8 @@ public function clear()
527654
throw new OptionDefinitionException('Options cannot be cleared anymore once options have been read.');
528655
}
529656

530-
$this->options = array();
531-
$this->lazy = array();
657+
$this->options = array();
658+
$this->lazy = array();
532659
$this->normalizers = array();
533660
}
534661

@@ -567,7 +694,7 @@ public function all()
567694
*
568695
* @param string $option The option name.
569696
*
570-
* @return bool Whether the option exists.
697+
* @return bool Whether the option exists.
571698
*
572699
* @see \ArrayAccess::offsetExists()
573700
*/
@@ -746,7 +873,7 @@ private function normalizeOption($option)
746873
/** @var \Closure $normalizer */
747874
$normalizer = $this->normalizers[$option];
748875

749-
< 1241 span class="pl-s1">$this->lock[$option] = true;
876+
$this->lock[$option] = true;
750877
$this->options[$option] = $normalizer($this, array_key_exists($option, $this->options) ? $this->options[$option] : null);
751878
unset($this->lock[$option]);
752879

0 commit comments

Comments
 (0)
0