Source of file Inflector.php
Size: 12,650 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/Filter/Inflector.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\Filter; use Traversable; use Zend\Stdlib\ArrayUtils; /** * Filter chain for string inflection */ class Inflector extends AbstractFilter { /** * @var FilterPluginManager */ protected $pluginManager = null; /** * @var string */ protected $target = null; /** * @var bool */ protected $throwTargetExceptionsOn = true; /** * @var string */ protected $targetReplacementIdentifier = ':'; /** * @var array */ protected $rules = array(); /** * Constructor * * @param string|array|Traversable $options Options to set */ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } if (!is_array($options)) { $options = func_get_args(); $temp = array(); if (!empty($options)) { $temp['target'] = array_shift($options); } if (!empty($options)) { $temp['rules'] = array_shift($options); } if (!empty($options)) { $temp['throwTargetExceptionsOn'] = array_shift($options); } if (!empty($options)) { $temp['targetReplacementIdentifier'] = array_shift($options); } $options = $temp; } $this->setOptions($options); } /** * Retrieve plugin manager * * @return FilterPluginManager */ public function getPluginManager() { if (!$this->pluginManager instanceof FilterPluginManager) { $this->setPluginManager(new FilterPluginManager()); } return $this->pluginManager; } /** * Set plugin manager * * @param FilterPluginManager $manager * @return self */ public function setPluginManager(FilterPluginManager $manager) { $this->pluginManager = $manager; return $this; } /** * Set options * * @param array|Traversable $options * @return self */ public function setOptions($options) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } // Set plugin manager if (array_key_exists('pluginManager', $options)) { if (is_scalar($options['pluginManager']) && class_exists($options['pluginManager'])) { $options['pluginManager'] = new $options['pluginManager']; } $this->setPluginManager($options['pluginManager']); } if (array_key_exists('throwTargetExceptionsOn', $options)) { $this->setThrowTargetExceptionsOn($options['throwTargetExceptionsOn']); } if (array_key_exists('targetReplacementIdentifier', $options)) { $this->setTargetReplacementIdentifier($options['targetReplacementIdentifier']); } if (array_key_exists('target', $options)) { $this->setTarget($options['target']); } if (array_key_exists('rules', $options)) { $this->addRules($options['rules']); } return $this; } /** * Set Whether or not the inflector should throw an exception when a replacement * identifier is still found within an inflected target. * * @param bool $throwTargetExceptionsOn * @return self */ public function setThrowTargetExceptionsOn($throwTargetExceptionsOn) { $this->throwTargetExceptionsOn = ($throwTargetExceptionsOn == true) ? true : false; return $this; } /** * Will exceptions be thrown? * * @return bool */ public function isThrowTargetExceptionsOn() { return $this->throwTargetExceptionsOn; } /** * Set the Target Replacement Identifier, by default ':' * * @param string $targetReplacementIdentifier * @return self */ public function setTargetReplacementIdentifier($targetReplacementIdentifier) { if ($targetReplacementIdentifier) { $this->targetReplacementIdentifier = (string) $targetReplacementIdentifier; } return $this; } /** * Get Target Replacement Identifier * * @return string */ public function getTargetReplacementIdentifier() { return $this->targetReplacementIdentifier; } /** * Set a Target * ex: 'scripts/:controller/:action.:suffix' * * @param string $target * @return self */ public function setTarget($target) { $this->target = (string) $target; return $this; } /** * Retrieve target * * @return string */ public function getTarget() { return $this->target; } /** * Set Target Reference * * @param reference $target * @return self */ public function setTargetReference(&$target) { $this->target =& $target; return $this; } /** * Is the same as calling addRules() with the exception that it * clears the rules before adding them. * * @param array $rules * @return self */ public function setRules(array $rules) { $this->clearRules(); $this->addRules($rules); return $this; } /** * Multi-call to setting filter rules. * * If prefixed with a ":" (colon), a filter rule will be added. If not * prefixed, a static replacement will be added. * * ex: * array( * ':controller' => array('CamelCaseToUnderscore', 'StringToLower'), * ':action' => array('CamelCaseToUnderscore', 'StringToLower'), * 'suffix' => 'phtml' * ); * * @param array $rules * @return self */ public function addRules(array $rules) { $keys = array_keys($rules); foreach ($keys as $spec) { if ($spec[0] == ':') { $this->addFilterRule($spec, $rules[$spec]); } else { $this->setStaticRule($spec, $rules[$spec]); } } return $this; } /** * Get rules * * By default, returns all rules. If a $spec is provided, will return those * rules if found, false otherwise. * * @param string $spec * @return array|false */ public function getRules($spec = null) { if (null !== $spec) { $spec = $this->_normalizeSpec($spec); if (isset($this->rules[$spec])) { return $this->rules[$spec]; } return false; } return $this->rules; } /** * Returns a rule set by setFilterRule(), a numeric index must be provided * * @param string $spec * @param int $index * @return FilterInterface|false */ public function getRule($spec, $index) { $spec = $this->_normalizeSpec($spec); if (isset($this->rules[$spec]) && is_array($this->rules[$spec])) { if (isset($this->rules[$spec][$index])) { return $this->rules[$spec][$index]; } } return false; } /** * Clears the rules currently in the inflector * * @return self */ public function clearRules() { $this->rules = array(); return $this; } /** * Set a filtering rule for a spec. $ruleSet can be a string, Filter object * or an array of strings or filter objects. * * @param string $spec * @param array|string|\Zend\Filter\FilterInterface $ruleSet * @return self */ public function setFilterRule($spec, $ruleSet) { $spec = $this->_normalizeSpec($spec); $this->rules[$spec] = array(); return $this->addFilterRule($spec, $ruleSet); } /** * Add a filter rule for a spec * * @param mixed $spec * @param mixed $ruleSet * @return self */ public function addFilterRule($spec, $ruleSet) { $spec = $this->_normalizeSpec($spec); if (!isset($this->rules[$spec])) { $this->rules[$spec] = array(); } if (!is_array($ruleSet)) { $ruleSet = array($ruleSet); } if (is_string($this->rules[$spec])) { $temp = $this->rules[$spec]; $this->rules[$spec] = array(); $this->rules[$spec][] = $temp; } foreach ($ruleSet as $rule) { $this->rules[$spec][] = $this->_getRule($rule); } return $this; } /** * Set a static rule for a spec. This is a single string value * * @param string $name * @param string $value * @return self */ public function setStaticRule($name, $value) { $name = $this->_normalizeSpec($name); $this->rules[$name] = (string) $value; return $this; } /** * Set Static Rule Reference. * * This allows a consuming class to pass a property or variable * in to be referenced when its time to build the output string from the * target. * * @param string $name * @param mixed $reference * @return self */ public function setStaticRuleReference($name, &$reference) { $name = $this->_normalizeSpec($name); $this->rules[$name] =& $reference; return $this; } /** * Inflect * * @param string|array $source * @throws Exception\RuntimeException * @return string */ public function filter($source) { // clean source foreach ((array) $source as $sourceName => $sourceValue) { $source[ltrim($sourceName, ':')] = $sourceValue; } $pregQuotedTargetReplacementIdentifier = preg_quote($this->targetReplacementIdentifier, '#'); $processedParts = array(); foreach ($this->rules as $ruleName => $ruleValue) { if (isset($source[$ruleName])) { if (is_string($ruleValue)) { // overriding the set rule $processedParts['#' . $pregQuotedTargetReplacementIdentifier . $ruleName . '#'] = str_replace('\\', '\\\\', $source[$ruleName]); } elseif (is_array($ruleValue)) { $processedPart = $source[$ruleName]; foreach ($ruleValue as $ruleFilter) { $processedPart = $ruleFilter($processedPart); } $processedParts['#' . $pregQuotedTargetReplacementIdentifier . $ruleName . '#'] = str_replace('\\', '\\\\', $processedPart); } } elseif (is_string($ruleValue)) { $processedParts['#' . $pregQuotedTargetReplacementIdentifier . $ruleName . '#'] = str_replace('\\', '\\\\', $ruleValue); } } // all of the values of processedParts would have been str_replace('\\', '\\\\', ..)'d to disable preg_replace backreferences $inflectedTarget = preg_replace(array_keys($processedParts), array_values($processedParts), $this->target); if ($this->throwTargetExceptionsOn && (preg_match('#(?=' . $pregQuotedTargetReplacementIdentifier.'[A-Za-z]{1})#', $inflectedTarget) == true)) { throw new Exception\RuntimeException('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); } return $inflectedTarget; } /** * Normalize spec string * * @param string $spec * @return string */ protected function _normalizeSpec($spec) { return ltrim((string) $spec, ':&'); } /** * Resolve named filters and convert them to filter objects. * * @param string $rule * @return FilterInterface */ protected function _getRule($rule) { if ($rule instanceof FilterInterface) { return $rule; } $rule = (string) $rule; return $this->getPluginManager()->get($rule); } } |