Configurable.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. namespace Symfony\Components\Form;
  3. use Symfony\Components\Form\Exception\MissingOptionsException;
  4. use Symfony\Components\Form\Exception\InvalidOptionsException;
  5. /**
  6. * A class configurable via options
  7. *
  8. * Options can be passed to the constructor of this class. After constructions,
  9. * these options cannot be changed anymore. This way, options remain light
  10. * weight. There is no need to monitor changes of options.
  11. *
  12. * If you want options that can change, you're recommended to implement plain
  13. * properties with setters and getters.
  14. *
  15. * @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
  16. */
  17. abstract class Configurable
  18. {
  19. /**
  20. * The options and their values
  21. * @var array
  22. */
  23. private $options = array();
  24. /**
  25. * The names of the valid options
  26. * @var array
  27. */
  28. private $knownOptions = array();
  29. /**
  30. * The names of the required options
  31. * @var array
  32. */
  33. private $requiredOptions = array();
  34. /**
  35. * The allowed values for each option
  36. * @var array
  37. */
  38. private $allowedValues = array();
  39. /**
  40. * Reads, validates and stores the given options
  41. *
  42. * @param array $options
  43. */
  44. public function __construct(array $options = array())
  45. {
  46. $this->options = array_merge($this->options, $options);
  47. $this->configure();
  48. // check option names
  49. if ($diff = array_diff_key($this->options, $this->knownOptions)) {
  50. throw new InvalidOptionsException(sprintf('%s does not support the following options: "%s".', get_class($this), implode('", "', array_keys($diff))), array_keys($diff));
  51. }
  52. // check required options
  53. if ($diff = array_diff_key($this->requiredOptions, $this->options)) {
  54. throw new MissingOptionsException(sprintf('%s requires the following options: \'%s\'.', get_class($this), implode('", "', array_keys($diff))), array_keys($diff));
  55. }
  56. }
  57. /**
  58. * Configures the valid options
  59. *
  60. * This method should call addOption() or addRequiredOption() for every
  61. * accepted option.
  62. */
  63. protected function configure()
  64. {
  65. }
  66. /**
  67. * Returns an option value.
  68. *
  69. * @param string $name The option name
  70. *
  71. * @return mixed The option value
  72. */
  73. public function getOption($name)
  74. {
  75. return array_key_exists($name, $this->options) ? $this->options[$name] : null;
  76. }
  77. /**
  78. * Adds a new option value with a default value.
  79. *
  80. * @param string $name The option name
  81. * @param mixed $value The default value
  82. */
  83. protected function addOption($name, $value = null, array $allowedValues = array())
  84. {
  85. $this->knownOptions[$name] = true;
  86. if (!array_key_exists($name, $this->options)) {
  87. $this->options[$name] = $value;
  88. }
  89. if (count($allowedValues) > 0 && !in_array($this->options[$name], $allowedValues)) {
  90. throw new InvalidOptionsException(sprintf('The option "%s" is expected to be one of "%s", but is "%s"', $name, implode('", "', $allowedValues), $this->options[$name]), array($name));
  91. }
  92. }
  93. /**
  94. * Adds a required option.
  95. *
  96. * @param string $name The option name
  97. */
  98. protected function addRequiredOption($name, array $allowedValues = array())
  99. {
  100. $this->knownOptions[$name] = true;
  101. $this->requiredOptions[$name] = true;
  102. // only test if the option is set, otherwise an error will be thrown
  103. // anyway
  104. if (isset($this->options[$name]) && count($allowedValues) > 0 && !in_array($this->options[$name], $allowedValues)) {
  105. throw new InvalidOptionsException(sprintf('The option "%s" is expected to be one of "%s", but is "%s"', $name, implode('", "', $allowedValues), $this->options[$name]), array($name));
  106. }
  107. }
  108. /**
  109. * Returns true if the option exists.
  110. *
  111. * @param string $name The option name
  112. *
  113. * @return bool true if the option is set, false otherwise
  114. */
  115. public function hasOption($name)
  116. {
  117. return isset($this->options[$name]);
  118. }
  119. }