Development

/branches/1.2/lib/plugins/sfCompat10Plugin/lib/config/sfValidatorConfigHandler.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfCompat10Plugin/lib/config/sfValidatorConfigHandler.class.php

Revision 8758, 16.7 kB (checked in by FabianLange, 7 years ago)

reverted more merge errors from r8755

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) 2004-2006 Sean Kerr <sean@code-box.org>
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 /**
13  * sfValidatorConfigHandler allows you to register validators with the system.
14  *
15  * @package    symfony
16  * @subpackage config
17  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
18  * @author     Sean Kerr <sean@code-box.org>
19  * @version    SVN: $Id$
20  */
21 class sfValidatorConfigHandler extends sfYamlConfigHandler
22 {
23   /**
24    * Executes this configuration handler.
25    *
26    * @param array An array of absolute filesystem path to a configuration file
27    *
28    * @return string Data to be written to a cache file
29    *
30    * @throws sfConfigurationException If a requested configuration file does not exist or is not readable
31    * @throws sfParseException If a requested configuration file is improperly formatted
32    */
33   public function execute($configFiles)
34   {
35     // parse the yaml
36     $config = $this->parseYamls($configFiles);
37
38     // alternate format?
39     if (isset($config['fields']))
40     {
41       $this->convertAlternate2Standard($config);
42     }
43
44     foreach (array('methods', 'names') as $category)
45     {
46       if (!isset($config[$category]))
47       {
48         if (!isset($config['fillin']))
49         {
50           throw new sfParseException(sprintf('Configuration file "%s" is missing "%s" category.', $configFiles[0], $category));
51         }
52         $config[$category] = array();
53       }
54     }
55
56     // init our data, includes, methods, names and validators arrays
57     $data       = array();
58     $includes   = array();
59     $methods    = array();
60     $names      = array();
61     $validators = array();
62
63     // get a list of methods and their registered files/parameters
64     foreach ($config['methods'] as $method => $list)
65     {
66       $method = strtoupper($method);
67
68       if (!isset($methods[$method]))
69       {
70         // make sure that this method is GET or POST
71         if ($method != 'GET' && $method != 'POST')
72         {
73           // unsupported request method
74           throw new sfParseException(sprintf('Configuration file "%s" specifies unsupported request method "%s".', $configFiles[0], $method));
75         }
76
77         // create our method
78         $methods[$method] = array();
79       }
80
81       if (!count($list))
82       {
83         // we have an empty list of names
84         continue;
85       }
86
87       // load name list
88       $this->loadNames($configFiles, $method, $methods, $names, $config, $list);
89     }
90
91     // load attribute list
92     $this->loadAttributes($configFiles, $methods, $names, $validators, $config, $list);
93
94     // fill-in filter configuration
95     $fillin = var_export(isset($config['fillin']) ? $config['fillin'] : array(), true);
96
97     // generate GET file/parameter data
98
99     $data[] = "if (\$_SERVER['REQUEST_METHOD'] == 'GET')";
100     $data[] = "{";
101
102     $this->generateRegistration('GET', $data, $methods, $names, $validators);
103
104     if (count($fillin))
105     {
106       $data[] = sprintf("  \$this->context->getRequest()->setAttribute('symfony.fillin', %s);", $fillin);
107     }
108
109     // generate POST file/parameter data
110
111     $data[] = "}";
112     $data[] = "else if (\$_SERVER['REQUEST_METHOD'] == 'POST')";
113     $data[] = "{";
114
115     $this->generateRegistration('POST', $data, $methods, $names, $validators);
116
117     if (count($fillin))
118     {
119       $data[] = sprintf("  \$this->context->getRequest()->setAttribute('symfony.fillin', %s);", $fillin);
120     }
121
122     $data[] = "}";
123
124     // compile data
125     $retval = sprintf("<?php\n".
126                       "// auto-generated by sfValidatorConfigHandler\n".
127                       "// date: %s\n%s\n%s\n", date('Y/m/d H:i:s'),
128                       implode("\n", $includes), implode("\n", $data));
129
130     return $retval;
131   }
132
133   /**
134    * Generates raw cache data.
135    *
136    * @param string A request method
137    * @param array  The data array where our cache code will be appended
138    * @param array  An associative array of request method data
139    * @param array  An associative array of file/parameter data
140    * @param array  A validators array
141    *
142    * @return boolean Returns true if there is some validators for this file/parameter
143    */
144   protected function generateRegistration($method, &$data, &$methods, &$names, &$validators)
145   {
146     // setup validator array
147     $data[] = "  \$validators = array();";
148
149     if (!isset($methods[$method]))
150     {
151       $methods[$method] = array();
152     }
153
154     // determine which validators we need to create for this request method
155     foreach ($methods[$method] as $name)
156     {
157       if (preg_match('/^([a-z0-9_-]+)\{([a-z0-9\s_-]+)\}$/i', $name, $match))
158       {
159         // this file/parameter has a parent
160         $subname = $match[2];
161         $parent  = $match[1];
162
163         $valList = $names[$parent][$subname]['validators'];
164       }
165       else
166       {
167         // no parent
168         $valList = $names[$name]['validators'];
169       }
170
171       if ($valList == null)
172       {
173         // no validator list for this file/parameter
174         continue;
175       }
176
177       foreach ($valList as $valName)
178       {
179         if (isset($validators[$valName]) && !isset($validators[$valName][$method]))
180         {
181           // retrieve this validator's info
182           $validator =& $validators[$valName];
183
184           $data[] = sprintf("  \$validators['%s'] = new %s(\$this->context, %s);\n",
185                             $valName, $validator['class'], $validator['parameters']);
186
187           // mark this validator as created for this request method
188           $validators[$valName][$method] = true;
189         }
190       }
191     }
192
193     foreach ($methods[$method] as $name)
194     {
195       if (preg_match('/^([a-z0-9_-]+)\{([a-z0-9\s_-]+)\}$/i', $name, $match))
196       {
197         // this file/parameter has a parent
198         $subname = $match[2];
199         $parent  = $match[1];
200         $name    = $match[2];
201
202         $attributes = $names[$parent][$subname];
203       }
204       else
205       {
206         // no parent
207         $attributes = $names[$name];
208       }
209
210       // register file/parameter
211       $data[] = sprintf("  \$validatorManager->registerName('%s', %s, %s, %s, %s, %s);",
212                         $name, $attributes['required'] ? 1 : 0,
213                         isset($attributes['required_msg']) ? $attributes['required_msg'] : "''",
214                         $attributes['parent'], $attributes['group'],
215                         $attributes['file']);
216
217       // register validators for this file/parameter
218       foreach ($attributes['validators'] as &$validator)
219       {
220         $data[] = sprintf("  \$validatorManager->registerValidator('%s', %s, %s);", $name,
221                           "\$validators['$validator']",
222                           $attributes['parent']);
223       }
224     }
225
226     return count($methods[$method]) ? true : false;
227   }
228
229   /**
230    * Loads the linear list of attributes from the [names] category.
231    *
232    * @param string The configuration file name (for exception usage)
233    * @param array  An associative array of request method data
234    * @param array  An associative array of file/parameter names in which to store loaded information
235    * @param array  An associative array of validator data
236    * @param array  The loaded ini configuration that we'll use for verification purposes
237    * @param string A comma delimited list of file/parameter names
238    */
239   protected function loadAttributes(&$configFiles, &$methods, &$names, &$validators, &$config, &$list)
240   {
241     foreach ($config['names'] as $name => $attributes)
242     {
243       // get a reference to the name entry
244       if (preg_match('/^([a-z0-9_-]+)\{([a-z0-9\s_-]+)\}$/i', $name, $match))
245       {
246         // this name entry has a parent
247         $subname = $match[2];
248         $parent  = $match[1];
249
250         if (!isset($names[$parent][$subname]))
251         {
252           // unknown parent or subname
253           throw new sfParseException(sprintf('Configuration file "%s" specifies unregistered parent "%s" or subname "%s".', $configFiles[0], $parent, $subname));
254         }
255
256         $entry =& $names[$parent][$subname];
257       }
258       else
259       {
260         // no parent
261         if (!isset($names[$name]))
262         {
263           // unknown name
264           throw new sfParseException(sprintf('Configuration file "%s" specifies unregistered name "%s".', $configFiles[0], $name));
265         }
266
267         $entry =& $names[$name];
268       }
269
270       foreach ($attributes as $attribute => $value)
271       {
272         if ($attribute == 'validators')
273         {
274           // load validators for this file/parameter name
275           $this->loadValidators($configFiles, $validators, $config, $value, $entry);
276         }
277         else if ($attribute == 'type')
278         {
279           // name type
280           $lvalue = strtolower($value);
281           $entry['file'] = ($lvalue == 'file' ? 'true' : 'false');
282         }
283         else
284         {
285           // just a normal attribute
286           $entry[$attribute] = sfToolkit::literalize($value, true);
287         }
288       }
289     }
290   }
291
292   /**
293    * Loads all request methods and the file/parameter names that will be
294    * validated from the [methods] category.
295    *
296    * @param string The configuration file name (for exception usage)
297    * @param string A request method
298    * @param array  An associative array of request method data
299    * @param array  An associative array of file/parameter names in which to store loaded information
300    * @param array  The loaded ini configuration that we'll use for verification purposes
301    * @param string A comma delimited list of file/parameter names
302    */
303   protected function loadNames(&$configFiles, &$method, &$methods, &$names, &$config, &$list)
304   {
305     // explode the list of names
306     $array = $list;
307
308     // loop through the names
309     foreach ($array as $name)
310     {
311       // make sure we have the required status of this file or parameter
312       if (!isset($config['names'][$name]['required']))
313       {
314         // missing 'required' attribute
315         throw new sfParseException(sprintf('Configuration file "%s" specifies file or parameter "%s", but it is missing the "required" attribute.', $configFiles[0], $name));
316       }
317
318       // determine parent status
319       if (preg_match('/^([a-z0-9_-]+)\{([a-z0-9\s_-]+)\}$/i', $name, $match))
320       {
321         // this name has a parent
322         $subname = $match[2];
323         $parent  = $match[1];
324
325         if (!isset($names[$parent]) || !isset($names[$parent][$name]))
326         {
327           if (!isset($names[$parent]))
328           {
329             // create our parent
330             $names[$parent] = array('_is_parent' => true);
331           }
332
333           // create our new name entry
334           $entry                 = array();
335           $entry['file']         = 'false';
336           $entry['group']        = 'null';
337           $entry['parent']       = "'$parent'";
338           $entry['required']     = 'true';
339           $entry['required_msg'] = "'Required'";
340           $entry['validators']   = array();
341
342           // add our name entry
343           $names[$parent][$subname] = $entry;
344         }
345       }
346       else if (strpos($name, '{') !== false || strpos($name, '}') !== false)
347       {
348         // name contains an invalid character
349         // this is most likely a typo where the user forgot to add a brace
350         throw new sfParseException(sprintf('Configuration file "%s" specifies method "%s" with invalid file/parameter name "%s".', $configFiles[0], $method, $name));
351       }
352       else
353       {
354         // no parent
355         if (!isset($names[$name]))
356         {
357           // create our new name entry
358           $entry                 = array();
359           $entry['file']         = 'false';
360           $entry['group']        = 'null';
361           $entry['parent']       = 'null';
362           $entry['required']     = 'true';
363           $entry['required_msg'] = "'Required'";
364           $entry['type']         = 'parameter';
365           $entry['validators']   = array();
366
367           // add our name entry
368           $names[$name] = $entry;
369         }
370       }
371
372       // add this name to the current request method
373       $methods[$method][] = $name;
374     }
375   }
376
377   /**
378    * Loads a list of validators.
379    *
380    * @param string The configuration file name (for exception usage)
381    * @param array  An associative array of validator data
382    * @param array  The loaded ini configuration that we'll use for verification purposes
383    * @param string A comma delimited list of validator names
384    * @param array  A file/parameter name entry
385    */
386   protected function loadValidators(&$configFiles, &$validators, &$config, &$list, &$entry)
387   {
388     // create our empty entry validator array
389     $entry['validators'] = array();
390
391     if (!$list || (!is_array($list) && trim($list) == ''))
392     {
393       // skip the empty list
394       return;
395     }
396
397     // get our validator array
398     $array = is_array($list) ? $list : explode(',', $list);
399
400     foreach ($array as $validator)
401     {
402       $validator = trim($validator);
403
404       // add this validator name to our entry
405       $entry['validators'][] = $validator;
406
407       // make sure the specified validator exists
408       if (!isset($config[$validator]))
409       {
410         // validator hasn't been registered
411         throw new sfParseException(sprintf('Configuration file "%s" specifies unregistered validator "%s".', $configFiles[0], $validator));
412       }
413
414       // has it already been registered?
415       if (isset($validators[$validator]))
416       {
417         continue;
418       }
419
420       if (!isset($config[$validator]['class']))
421       {
422         // missing class key
423         throw new sfParseException(sprintf('Configuration file "%s" specifies category "%s" with missing class key.', $configFiles[0], $validator));
424       }
425
426       // create our validator
427       $validators[$validator]               = array();
428       $validators[$validator]['class']      = $config[$validator]['class'];
429       $validators[$validator]['file']       = null;
430       $validators[$validator]['parameters'] = null;
431
432       if (isset($config[$validator]['file']))
433       {
434         // we have a file for this validator
435         $file = $config[$validator]['file'];
436
437         // keyword replacement
438         $file = $this->replaceConstants($file);
439         $file = $this->replacePath($file);
440
441         if (!is_readable($file))
442         {
443           // file doesn't exist
444           throw new sfParseException(sprintf('Configuration file "%s" specifies category "%s" with nonexistent or unreadable file "%s".', $configFiles[0], $validator, $file));
445         }
446
447         $validators[$validator]['file'] = $file;
448       }
449
450       // parse parameters
451       $parameters = (isset($config[$validator]['param']) ? var_export($config[$validator]['param'], true) : 'null');
452
453       $validators[$validator]['parameters'] = $parameters;
454     }
455   }
456
457   /**
458    * Converts alternate format to standard format.
459    *
460    * @param array  Configuration data
461    */
462   protected function convertAlternate2Standard(&$config)
463   {
464     $defaultMethods = isset($config['methods']) ? $config['methods'] : array('post');
465     $config['methods'] = array();
466
467     // validators
468     if (isset($config['validators']))
469     {
470       foreach ((array) $config['validators'] as $validator => $params)
471       {
472         $config[$validator] = $params;
473       }
474
475       unset($config['validators']);
476     }
477
478     // names
479     $config['names'] = $config['fields'];
480     unset($config['fields']);
481
482     foreach ($config['names'] as $name => $values)
483     {
484       // validators
485       $validators = array();
486       foreach ($values as $validator => $params)
487       {
488         if (in_array($validator, array('required', 'group', 'group_msg', 'parent', 'file', 'methods')))
489         {
490           continue;
491         }
492
493         // class or validator
494         if (!isset($config[$validator]))
495         {
496           $config[$validator] = array('class' => $validator);
497         }
498
499         $validatorName = $validator;
500         if ($params)
501         {
502           // create a new validator
503           $validatorName = $validator.'_'.$name;
504           $config[$validatorName] = $config[$validator];
505           $config[$validatorName]['param'] = array_merge(isset($config[$validator]['param']) ? (array) $config[$validator]['param'] : array(), $params);
506         }
507
508         $validators[] = $validatorName;
509
510         unset($values[$validator]);
511       }
512       $values['validators'] = $validators;
513
514       // group
515       if (isset($values['group']) && isset($values['group_msg']))
516       {
517         $values['required_msg'] = $values['group_msg'];
518       }
519
520       // required
521       if (isset($values['required']))
522       {
523         $values['required_msg'] = $values['required']['msg'];
524         $values['required'] = true;
525       }
526       else
527       {
528         $values['required'] = false;
529       }
530
531       // methods
532       if (isset($values['methods']))
533       {
534         $methods = (array) $values['methods'];
535         unset($values['methods']);
536       }
537       else
538       {
539         $methods = $defaultMethods;
540       }
541       foreach ($methods as $method)
542       {
543         $config['methods'][$method][] = $name;
544       }
545
546       $config['names'][$name] = $values;
547     }
548   }
549 }
550
Note: See TracBrowser for help on using the browser.