setConfig($target); } else { if ((null !== $target) && is_string($target)) { $this->setTarget($target); } if (null !== $rules) { $this->addRules($rules); } if ($throwTargetExceptionsOn !== null) { $this->setThrowTargetExceptionsOn($throwTargetExceptionsOn); } if ($targetReplacementIdentifer != '') { $this->setTargetReplacementIdentifier($targetReplacementIdentifer); } } } /** * Retreive PluginLoader * * @return Zend_Loader_PluginLoader_Interface */ public function getPluginLoader() { if (!$this->_pluginLoader instanceof Zend_Loader_PluginLoader_Interface) { $this->_pluginLoader = new Zend_Loader_PluginLoader(array('Zend_Filter_' => 'Zend/Filter/'), __CLASS__); } return $this->_pluginLoader; } /** * Set PluginLoader * * @param Zend_Loader_PluginLoader_Interface $pluginLoader * @return Zend_Filter_Inflector */ public function setPluginLoader(Zend_Loader_PluginLoader_Interface $pluginLoader) { $this->_pluginLoader = $pluginLoader; return $this; } /** * Use Zend_Config object to set object state * * @param Zend_Config $config * @return Zend_Filter_Inflector */ public function setConfig(Zend_Config $config) { foreach ($config as $key => $value) { switch ($key) { case 'target': $this->setTarget($value); break; case 'filterPrefixPath': if (is_scalar($value)) { break; } $paths = $value->toArray(); foreach ($paths as $prefix => $path) { $this->addFilterPrefixPath($prefix, $path); } break; case 'throwTargetExceptionsOn': $this->setThrowTargetExceptionsOn($value); break; case 'targetReplacementIdentifier': $this->setTargetReplacementIdentifier($value); break; case 'rules': $this->addRules($value->toArray()); break; default: break; } } return $this; } /** * Convienence method to add prefix and path to PluginLoader * * @param string $prefix * @param string $path * @return Zend_Filter_Inflector */ public function addFilterPrefixPath($prefix, $path) { $this->getPluginLoader()->addPrefixPath($prefix, $path); 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 $throwTargetExceptions * @return Zend_Filter_Inflector */ 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 Zend_Filter_Inflector */ public function setTargetReplacementIdentifier($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 * @return Zend_Filter_Inflector */ 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 Zend_Filter_Inflector */ public function setTargetReference(&$target) { $this->_target =& $target; return $this; } /** * SetRules() is the same as calling addRules() with the exception that it * clears the rules before adding them. * * @param array $rules * @return Zend_Filter_Inflector */ public function setRules(Array $rules) { $this->clearRules(); $this->addRules($rules); return $this; } /** * AddRules(): 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 * @return Zend_Filter_Inflector */ 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; } /** * getRule() returns a rule set by setFilterRule(), a numeric index must be provided * * @param string $spec * @param int $index * @return Zend_Filter_Interface|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; } /** * ClearRules() clears the rules currently in the inflector * * @return Zend_Filter_Inflector */ 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_Interface $ruleSet * @return Zend_Filter_Inflector */ 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 void */ 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); } 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 Zend_Filter_Inflector */ 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 Zend_Filter_Inflector */ public function setStaticRuleReference($name, &$reference) { $name = $this->_normalizeSpec($name); $this->_rules[$name] =& $reference; return $this; } /** * Inflect * * @param string|array $source * @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->filter($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)) { require_once 'Zend/Filter/Exception.php'; 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); } 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 Zend_Filter_Interface */ protected function _getRule($rule) { if ($rule instanceof Zend_Filter_Interface) { return $rule; } $rule = (string) $rule; $className = $this->getPluginLoader()->load($rule); $ruleObject = new $className(); if (!$ruleObject instanceof Zend_Filter_Interface) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('No class named ' . $rule . ' implementing Zend_Filter_Interface could be found'); } return $ruleObject; } }