1: <?php
2:
3: /*
4: * This file is part of the Symfony package.
5: *
6: * (c) Fabien Potencier <fabien@symfony.com>
7: *
8: * For the full copyright and license information, please view the LICENSE
9: * file that was distributed with this source code.
10: */
11:
12: namespace Symfony\Component\HttpFoundation;
13:
14: /**
15: * ParameterBag is a container for key/value pairs.
16: *
17: * @author Fabien Potencier <fabien@symfony.com>
18: *
19: * @api
20: */
21: class ParameterBag implements \IteratorAggregate, \Countable
22: {
23: /**
24: * Parameter storage.
25: *
26: * @var array
27: */
28: protected $parameters;
29:
30: /**
31: * Constructor.
32: *
33: * @param array $parameters An array of parameters
34: *
35: * @api
36: */
37: public function __construct(array $parameters = array())
38: {
39: $this->parameters = $parameters;
40: }
41:
42: /**
43: * Returns the parameters.
44: *
45: * @return array An array of parameters
46: *
47: * @api
48: */
49: public function all()
50: {
51: return $this->parameters;
52: }
53:
54: /**
55: * Returns the parameter keys.
56: *
57: * @return array An array of parameter keys
58: *
59: * @api
60: */
61: public function keys()
62: {
63: return array_keys($this->parameters);
64: }
65:
66: /**
67: * Replaces the current parameters by a new set.
68: *
69: * @param array $parameters An array of parameters
70: *
71: * @api
72: */
73: public function replace(array $parameters = array())
74: {
75: $this->parameters = $parameters;
76: }
77:
78: /**
79: * Adds parameters.
80: *
81: * @param array $parameters An array of parameters
82: *
83: * @api
84: */
85: public function add(array $parameters = array())
86: {
87: $this->parameters = array_replace($this->parameters, $parameters);
88: }
89:
90: /**
91: * Returns a parameter by name.
92: *
93: * @param string $path The key
94: * @param mixed $default The default value if the parameter key does not exist
95: * @param boolean $deep If true, a path like foo[bar] will find deeper items
96: *
97: * @return mixed
98: *
99: * @throws \InvalidArgumentException
100: *
101: * @api
102: */
103: public function get($path, $default = null, $deep = false)
104: {
105: if (!$deep || false === $pos = strpos($path, '[')) {
106: return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default;
107: }
108:
109: $root = substr($path, 0, $pos);
110: if (!array_key_exists($root, $this->parameters)) {
111: return $default;
112: }
113:
114: $value = $this->parameters[$root];
115: $currentKey = null;
116: for ($i = $pos, $c = strlen($path); $i < $c; $i++) {
117: $char = $path[$i];
118:
119: if ('[' === $char) {
120: if (null !== $currentKey) {
121: throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i));
122: }
123:
124: $currentKey = '';
125: } elseif (']' === $char) {
126: if (null === $currentKey) {
127: throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i));
128: }
129:
130: if (!is_array($value) || !array_key_exists($currentKey, $value)) {
131: return $default;
132: }
133:
134: $value = $value[$currentKey];
135: $currentKey = null;
136: } else {
137: if (null === $currentKey) {
138: throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i));
139: }
140:
141: $currentKey .= $char;
142: }
143: }
144:
145: if (null !== $currentKey) {
146: throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".'));
147: }
148:
149: return $value;
150: }
151:
152: /**
153: * Sets a parameter by name.
154: *
155: * @param string $key The key
156: * @param mixed $value The value
157: *
158: * @api
159: */
160: public function set($key, $value)
161: {
162: $this->parameters[$key] = $value;
163: }
164:
165: /**
166: * Returns true if the parameter is defined.
167: *
168: * @param string $key The key
169: *
170: * @return Boolean true if the parameter exists, false otherwise
171: *
172: * @api
173: */
174: public function has($key)
175: {
176: return array_key_exists($key, $this->parameters);
177: }
178:
179: /**
180: * Removes a parameter.
181: *
182: * @param string $key The key
183: *
184: * @api
185: */
186: public function remove($key)
187: {
188: unset($this->parameters[$key]);
189: }
190:
191: /**
192: * Returns the alphabetic characters of the parameter value.
193: *
194: * @param string $key The parameter key
195: * @param mixed $default The default value if the parameter key does not exist
196: * @param boolean $deep If true, a path like foo[bar] will find deeper items
197: *
198: * @return string The filtered value
199: *
200: * @api
201: */
202: public function getAlpha($key, $default = '', $deep = false)
203: {
204: return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep));
205: }
206:
207: /**
208: * Returns the alphabetic characters and digits of the parameter value.
209: *
210: * @param string $key The parameter key
211: * @param mixed $default The default value if the parameter key does not exist
212: * @param boolean $deep If true, a path like foo[bar] will find deeper items
213: *
214: * @return string The filtered value
215: *
216: * @api
217: */
218: public function getAlnum($key, $default = '', $deep = false)
219: {
220: return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep));
221: }
222:
223: /**
224: * Returns the digits of the parameter value.
225: *
226: * @param string $key The parameter key
227: * @param mixed $default The default value if the parameter key does not exist
228: * @param boolean $deep If true, a path like foo[bar] will find deeper items
229: *
230: * @return string The filtered value
231: *
232: * @api
233: */
234: public function getDigits($key, $default = '', $deep = false)
235: {
236: // we need to remove - and + because they're allowed in the filter
237: return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT));
238: }
239:
240: /**
241: * Returns the parameter value converted to integer.
242: *
243: * @param string $key The parameter key
244: * @param mixed $default The default value if the parameter key does not exist
245: * @param boolean $deep If true, a path like foo[bar] will find deeper items
246: *
247: * @return integer The filtered value
248: *
249: * @api
250: */
251: public function getInt($key, $default = 0, $deep = false)
252: {
253: return (int) $this->get($key, $default, $deep);
254: }
255:
256: /**
257: * Filter key.
258: *
259: * @param string $key Key.
260: * @param mixed $default Default = null.
261: * @param boolean $deep Default = false.
262: * @param integer $filter FILTER_* constant.
263: * @param mixed $options Filter options.
264: *
265: * @see http://php.net/manual/en/function.filter-var.php
266: *
267: * @return mixed
268: */
269: public function filter($key, $default = null, $deep = false, $filter=FILTER_DEFAULT, $options=array())
270: {
271: $value = $this->get($key, $default, $deep);
272:
273: // Always turn $options into an array - this allows filter_var option shortcuts.
274: if (!is_array($options) && $options) {
275: $options = array('flags' => $options);
276: }
277:
278: // Add a convenience check for arrays.
279: if (is_array($value) && !isset($options['flags'])) {
280: $options['flags'] = FILTER_REQUIRE_ARRAY;
281: }
282:
283: return filter_var($value, $filter, $options);
284: }
285:
286: /**
287: * Returns an iterator for parameters.
288: *
289: * @return \ArrayIterator An \ArrayIterator instance
290: */
291: public function getIterator()
292: {
293: return new \ArrayIterator($this->parameters);
294: }
295:
296: /**
297: * Returns the number of parameters.
298: *
299: * @return int The number of parameters
300: */
301: public function count()
302: {
303: return count($this->parameters);
304: }
305: }
306: