scratch – Blame information for rev 87

Subversion Repositories:
Rev:
Rev Author Line No. Line
87 office 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\DomCrawler;
13  
14 use Symfony\Component\DomCrawler\Field\FormField;
15  
16 /**
17 * This is an internal class that must not be used directly.
18 *
19 * @internal
20 */
21 class FormFieldRegistry
22 {
23 private $fields = array();
24  
25 private $base;
26  
27 /**
28 * Adds a field to the registry.
29 *
30 * @param FormField $field The field
31 */
32 public function add(FormField $field)
33 {
34 $segments = $this->getSegments($field->getName());
35  
36 $target = &$this->fields;
37 while ($segments) {
38 if (!is_array($target)) {
39 $target = array();
40 }
41 $path = array_shift($segments);
42 if ('' === $path) {
43 $target = &$target[];
44 } else {
45 $target = &$target[$path];
46 }
47 }
48 $target = $field;
49 }
50  
51 /**
52 * Removes a field and its children from the registry.
53 *
54 * @param string $name The fully qualified name of the base field
55 */
56 public function remove($name)
57 {
58 $segments = $this->getSegments($name);
59 $target = &$this->fields;
60 while (count($segments) > 1) {
61 $path = array_shift($segments);
62 if (!array_key_exists($path, $target)) {
63 return;
64 }
65 $target = &$target[$path];
66 }
67 unset($target[array_shift($segments)]);
68 }
69  
70 /**
71 * Returns the value of the field and its children.
72 *
73 * @param string $name The fully qualified name of the field
74 *
75 * @return mixed The value of the field
76 *
77 * @throws \InvalidArgumentException if the field does not exist
78 */
79 public function &get($name)
80 {
81 $segments = $this->getSegments($name);
82 $target = &$this->fields;
83 while ($segments) {
84 $path = array_shift($segments);
85 if (!array_key_exists($path, $target)) {
86 throw new \InvalidArgumentException(sprintf('Unreachable field "%s"', $path));
87 }
88 $target = &$target[$path];
89 }
90  
91 return $target;
92 }
93  
94 /**
95 * Tests whether the form has the given field.
96 *
97 * @param string $name The fully qualified name of the field
98 *
99 * @return bool Whether the form has the given field
100 */
101 public function has($name)
102 {
103 try {
104 $this->get($name);
105  
106 return true;
107 } catch (\InvalidArgumentException $e) {
108 return false;
109 }
110 }
111  
112 /**
113 * Set the value of a field and its children.
114 *
115 * @param string $name The fully qualified name of the field
116 * @param mixed $value The value
117 *
118 * @throws \InvalidArgumentException if the field does not exist
119 */
120 public function set($name, $value)
121 {
122 $target = &$this->get($name);
123 if ((!is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) {
124 $target->setValue($value);
125 } elseif (is_array($value)) {
126 $fields = self::create($name, $value);
127 foreach ($fields->all() as $k => $v) {
128 $this->set($k, $v);
129 }
130 } else {
131 throw new \InvalidArgumentException(sprintf('Cannot set value on a compound field "%s".', $name));
132 }
133 }
134  
135 /**
136 * Returns the list of field with their value.
137 *
138 * @return FormField[] The list of fields as array((string) Fully qualified name => (mixed) value)
139 */
140 public function all()
141 {
142 return $this->walk($this->fields, $this->base);
143 }
144  
145 /**
146 * Creates an instance of the class.
147 *
148 * This function is made private because it allows overriding the $base and
149 * the $values properties without any type checking.
150 *
151 * @param string $base The fully qualified name of the base field
152 * @param array $values The values of the fields
153 *
154 * @return static
155 */
156 private static function create($base, array $values)
157 {
158 $registry = new static();
159 $registry->base = $base;
160 $registry->fields = $values;
161  
162 return $registry;
163 }
164  
165 /**
166 * Transforms a PHP array in a list of fully qualified name / value.
167 *
168 * @param array $array The PHP array
169 * @param string $base The name of the base field
170 * @param array $output The initial values
171 *
172 * @return array The list of fields as array((string) Fully qualified name => (mixed) value)
173 */
174 private function walk(array $array, $base = '', array &$output = array())
175 {
176 foreach ($array as $k => $v) {
177 $path = empty($base) ? $k : sprintf('%s[%s]', $base, $k);
178 if (is_array($v)) {
179 $this->walk($v, $path, $output);
180 } else {
181 $output[$path] = $v;
182 }
183 }
184  
185 return $output;
186 }
187  
188 /**
189 * Splits a field name into segments as a web browser would do.
190 *
191 * <code>
192 * getSegments('base[foo][3][]') = array('base', 'foo, '3', '');
193 * </code>
194 *
195 * @param string $name The name of the field
196 *
197 * @return string[] The list of segments
198 */
199 private function getSegments($name)
200 {
201 if (preg_match('/^(?P<base>[^[]+)(?P<extra>(\[.*)|$)/', $name, $m)) {
202 $segments = array($m['base']);
203 while (!empty($m['extra'])) {
204 $extra = $m['extra'];
205 if (preg_match('/^\[(?P<segment>.*?)\](?P<extra>.*)$/', $extra, $m)) {
206 $segments[] = $m['segment'];
207 } else {
208 $segments[] = $extra;
209 }
210 }
211  
212 return $segments;
213 }
214  
215 return array($name);
216 }
217 }