[I18N] Zend_Filter/Zend_Validate:
[zend.git] / library / Zend / Filter / Inflector.php
blobce120149eafd0b514be524ef7de5e1d75c5d8a59
1 <?php
2 /**
3 * Zend Framework
5 * LICENSE
7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
15 * @category Zend
16 * @package Zend_Filter
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license http://framework.zend.com/license/new-bsd New BSD License
19 * @version $Id$
22 /**
23 * @see Zend_Filter
24 * @see Zend_Filter_Interface
26 require_once 'Zend/Filter.php';
28 /**
29 * @see Zend_Loader_PluginLoader
31 require_once 'Zend/Loader/PluginLoader.php';
33 /**
34 * Filter chain for string inflection
36 * @category Zend
37 * @package Zend_Filter
38 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
39 * @license http://framework.zend.com/license/new-bsd New BSD License
41 class Zend_Filter_Inflector implements Zend_Filter_Interface
43 /**
44 * @var Zend_Loader_PluginLoader_Interface
46 protected $_pluginLoader = null;
48 /**
49 * @var string
51 protected $_target = null;
53 /**
54 * @var bool
56 protected $_throwTargetExceptionsOn = true;
58 /**
59 * @var string
61 protected $_targetReplacementIdentifier = ':';
63 /**
64 * @var array
66 protected $_rules = array();
68 /**
69 * Constructor
71 * @param string|array $options Options to set
73 public function __construct($options = null)
75 if ($options instanceof Zend_Config) {
76 $options = $options->toArray();
77 } else if (!is_array($options)) {
78 $options = func_get_args();
79 $temp = array();
81 if (!empty($options)) {
82 $temp['target'] = array_shift($options);
85 if (!empty($options)) {
86 $temp['rules'] = array_shift($options);
89 if (!empty($options)) {
90 $temp['throwTargetExceptionsOn'] = array_shift($options);
93 if (!empty($options)) {
94 $temp['targetReplacementIdentifier'] = array_shift($options);
97 $options = $temp;
100 $this->setOptions($options);
104 * Retreive PluginLoader
106 * @return Zend_Loader_PluginLoader_Interface
108 public function getPluginLoader()
110 if (!$this->_pluginLoader instanceof Zend_Loader_PluginLoader_Interface) {
111 $this->_pluginLoader = new Zend_Loader_PluginLoader(array('Zend_Filter_' => 'Zend/Filter/'), __CLASS__);
114 return $this->_pluginLoader;
118 * Set PluginLoader
120 * @param Zend_Loader_PluginLoader_Interface $pluginLoader
121 * @return Zend_Filter_Inflector
123 public function setPluginLoader(Zend_Loader_PluginLoader_Interface $pluginLoader)
125 $this->_pluginLoader = $pluginLoader;
126 return $this;
130 * Use Zend_Config object to set object state
132 * @deprecated Use setOptions() instead
133 * @param Zend_Config $config
134 * @return Zend_Filter_Inflector
136 public function setConfig(Zend_Config $config)
138 return $this->setOptions($config);
142 * Set options
144 * @param array $options
145 * @return Zend_Filter_Inflector
147 public function setOptions($options) {
148 if ($options instanceof Zend_Config) {
149 $options = $options->toArray();
152 // Set Präfix Path
153 if (array_key_exists('filterPrefixPath', $options)) {
154 if (!is_scalar($options['filterPrefixPath'])) {
155 foreach ($options['filterPrefixPath'] as $prefix => $path) {
156 $this->addFilterPrefixPath($prefix, $path);
161 if (array_key_exists('throwTargetExceptionsOn', $options)) {
162 $this->setThrowTargetExceptionsOn($options['throwTargetExceptionsOn']);
165 if (array_key_exists('targetReplacementIdentifier', $options)) {
166 $this->setTargetReplacementIdentifier($options['targetReplacementIdentifier']);
169 if (array_key_exists('target', $options)) {
170 $this->setTarget($options['target']);
173 if (array_key_exists('rules', $options)) {
174 $this->addRules($options['rules']);
177 return $this;
181 * Convienence method to add prefix and path to PluginLoader
183 * @param string $prefix
184 * @param string $path
185 * @return Zend_Filter_Inflector
187 public function addFilterPrefixPath($prefix, $path)
189 $this->getPluginLoader()->addPrefixPath($prefix, $path);
190 return $this;
194 * Set Whether or not the inflector should throw an exception when a replacement
195 * identifier is still found within an inflected target.
197 * @param bool $throwTargetExceptions
198 * @return Zend_Filter_Inflector
200 public function setThrowTargetExceptionsOn($throwTargetExceptionsOn)
202 $this->_throwTargetExceptionsOn = ($throwTargetExceptionsOn == true) ? true : false;
203 return $this;
207 * Will exceptions be thrown?
209 * @return bool
211 public function isThrowTargetExceptionsOn()
213 return $this->_throwTargetExceptionsOn;
217 * Set the Target Replacement Identifier, by default ':'
219 * @param string $targetReplacementIdentifier
220 * @return Zend_Filter_Inflector
222 public function setTargetReplacementIdentifier($targetReplacementIdentifier)
224 if ($targetReplacementIdentifier) {
225 $this->_targetReplacementIdentifier = (string) $targetReplacementIdentifier;
228 return $this;
232 * Get Target Replacement Identifier
234 * @return string
236 public function getTargetReplacementIdentifier()
238 return $this->_targetReplacementIdentifier;
242 * Set a Target
243 * ex: 'scripts/:controller/:action.:suffix'
245 * @param string
246 * @return Zend_Filter_Inflector
248 public function setTarget($target)
250 $this->_target = (string) $target;
251 return $this;
255 * Retrieve target
257 * @return string
259 public function getTarget()
261 return $this->_target;
265 * Set Target Reference
267 * @param reference $target
268 * @return Zend_Filter_Inflector
270 public function setTargetReference(&$target)
272 $this->_target =& $target;
273 return $this;
277 * SetRules() is the same as calling addRules() with the exception that it
278 * clears the rules before adding them.
280 * @param array $rules
281 * @return Zend_Filter_Inflector
283 public function setRules(Array $rules)
285 $this->clearRules();
286 $this->addRules($rules);
287 return $this;
291 * AddRules(): multi-call to setting filter rules.
293 * If prefixed with a ":" (colon), a filter rule will be added. If not
294 * prefixed, a static replacement will be added.
296 * ex:
297 * array(
298 * ':controller' => array('CamelCaseToUnderscore','StringToLower'),
299 * ':action' => array('CamelCaseToUnderscore','StringToLower'),
300 * 'suffix' => 'phtml'
301 * );
303 * @param array
304 * @return Zend_Filter_Inflector
306 public function addRules(Array $rules)
308 $keys = array_keys($rules);
309 foreach ($keys as $spec) {
310 if ($spec[0] == ':') {
311 $this->addFilterRule($spec, $rules[$spec]);
312 } else {
313 $this->setStaticRule($spec, $rules[$spec]);
317 return $this;
321 * Get rules
323 * By default, returns all rules. If a $spec is provided, will return those
324 * rules if found, false otherwise.
326 * @param string $spec
327 * @return array|false
329 public function getRules($spec = null)
331 if (null !== $spec) {
332 $spec = $this->_normalizeSpec($spec);
333 if (isset($this->_rules[$spec])) {
334 return $this->_rules[$spec];
336 return false;
339 return $this->_rules;
343 * getRule() returns a rule set by setFilterRule(), a numeric index must be provided
345 * @param string $spec
346 * @param int $index
347 * @return Zend_Filter_Interface|false
349 public function getRule($spec, $index)
351 $spec = $this->_normalizeSpec($spec);
352 if (isset($this->_rules[$spec]) && is_array($this->_rules[$spec])) {
353 if (isset($this->_rules[$spec][$index])) {
354 return $this->_rules[$spec][$index];
357 return false;
361 * ClearRules() clears the rules currently in the inflector
363 * @return Zend_Filter_Inflector
365 public function clearRules()
367 $this->_rules = array();
368 return $this;
372 * Set a filtering rule for a spec. $ruleSet can be a string, Filter object
373 * or an array of strings or filter objects.
375 * @param string $spec
376 * @param array|string|Zend_Filter_Interface $ruleSet
377 * @return Zend_Filter_Inflector
379 public function setFilterRule($spec, $ruleSet)
381 $spec = $this->_normalizeSpec($spec);
382 $this->_rules[$spec] = array();
383 return $this->addFilterRule($spec, $ruleSet);
387 * Add a filter rule for a spec
389 * @param mixed $spec
390 * @param mixed $ruleSet
391 * @return void
393 public function addFilterRule($spec, $ruleSet)
395 $spec = $this->_normalizeSpec($spec);
396 if (!isset($this->_rules[$spec])) {
397 $this->_rules[$spec] = array();
400 if (!is_array($ruleSet)) {
401 $ruleSet = array($ruleSet);
404 if (is_string($this->_rules[$spec])) {
405 $temp = $this->_rules[$spec];
406 $this->_rules[$spec] = array();
407 $this->_rules[$spec][] = $temp;
410 foreach ($ruleSet as $rule) {
411 $this->_rules[$spec][] = $this->_getRule($rule);
414 return $this;
418 * Set a static rule for a spec. This is a single string value
420 * @param string $name
421 * @param string $value
422 * @return Zend_Filter_Inflector
424 public function setStaticRule($name, $value)
426 $name = $this->_normalizeSpec($name);
427 $this->_rules[$name] = (string) $value;
428 return $this;
432 * Set Static Rule Reference.
434 * This allows a consuming class to pass a property or variable
435 * in to be referenced when its time to build the output string from the
436 * target.
438 * @param string $name
439 * @param mixed $reference
440 * @return Zend_Filter_Inflector
442 public function setStaticRuleReference($name, &$reference)
444 $name = $this->_normalizeSpec($name);
445 $this->_rules[$name] =& $reference;
446 return $this;
450 * Inflect
452 * @param string|array $source
453 * @return string
455 public function filter($source)
457 // clean source
458 foreach ( (array) $source as $sourceName => $sourceValue) {
459 $source[ltrim($sourceName, ':')] = $sourceValue;
462 $pregQuotedTargetReplacementIdentifier = preg_quote($this->_targetReplacementIdentifier, '#');
463 $processedParts = array();
465 foreach ($this->_rules as $ruleName => $ruleValue) {
466 if (isset($source[$ruleName])) {
467 if (is_string($ruleValue)) {
468 // overriding the set rule
469 $processedParts['#'.$pregQuotedTargetReplacementIdentifier.$ruleName.'#'] = str_replace('\\', '\\\\', $source[$ruleName]);
470 } elseif (is_array($ruleValue)) {
471 $processedPart = $source[$ruleName];
472 foreach ($ruleValue as $ruleFilter) {
473 $processedPart = $ruleFilter->filter($processedPart);
475 $processedParts['#'.$pregQuotedTargetReplacementIdentifier.$ruleName.'#'] = str_replace('\\', '\\\\', $processedPart);
477 } elseif (is_string($ruleValue)) {
478 $processedParts['#'.$pregQuotedTargetReplacementIdentifier.$ruleName.'#'] = str_replace('\\', '\\\\', $ruleValue);
482 // all of the values of processedParts would have been str_replace('\\', '\\\\', ..)'d to disable preg_replace backreferences
483 $inflectedTarget = preg_replace(array_keys($processedParts), array_values($processedParts), $this->_target);
485 if ($this->_throwTargetExceptionsOn && (preg_match('#(?='.$pregQuotedTargetReplacementIdentifier.'[A-Za-z]{1})#', $inflectedTarget) == true)) {
486 require_once 'Zend/Filter/Exception.php';
487 throw new Zend_Filter_Exception('A replacement identifier ' . $this->_targetReplacementIdentifier . ' was found inside the inflected target, perhaps a rule was not satisfied with a target source? Unsatisfied inflected target: ' . $inflectedTarget);
490 return $inflectedTarget;
494 * Normalize spec string
496 * @param string $spec
497 * @return string
499 protected function _normalizeSpec($spec)
501 return ltrim((string) $spec, ':&');
505 * Resolve named filters and convert them to filter objects.
507 * @param string $rule
508 * @return Zend_Filter_Interface
510 protected function _getRule($rule)
512 if ($rule instanceof Zend_Filter_Interface) {
513 return $rule;
516 $rule = (string) $rule;
518 $className = $this->getPluginLoader()->load($rule);
519 $ruleObject = new $className();
520 if (!$ruleObject instanceof Zend_Filter_Interface) {
521 require_once 'Zend/Filter/Exception.php';
522 throw new Zend_Filter_Exception('No class named ' . $rule . ' implementing Zend_Filter_Interface could be found');
525 return $ruleObject;