Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0de9a59

Browse filesBrowse 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
Copy full SHA for 0de9a59

File tree

1 file changed

+145
-18
lines changed
Filter options

1 file changed

+145
-18
lines changed

‎src/Symfony/Component/OptionsResolver/Options.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/OptionsResolver/Options.php
+145-18Lines 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-
$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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.