ZF-5558: CLONE -Zend_Controller_Router_Route_Regex won't assemble when used with xml config
Description
When setting a reverse route through an xml config file, the assemble method of the regex route fails. The _getMappedValues method expects it's map to be in index => key form:
$index = (!is_int($key)) ? array_search($key, $this->_map, true) : $key;
this will fail when used with xml, which doesn't support this, a sample config could contain:
1
2
By limitation of xml this is different from the ini config and manual setup. When parsing the url this isn't a problem, but the assemble method fails to get any parts from the _getMappedValues method to parse into the query string and throws an exception. It can easily solved by modifying the method a little:
$index = (!is_int($key)) ? array_search($key, $this->_map, true) : $key;
if (false !== $index) {
$return[$index] = $values[$key];
} elseif (isset($this->_map[$key])) {
//non-numerical setup
$return[$key] = $this->_map[$key];
}
Comments
Posted by Robert Hänsel (r-o-b-e-r-t) on 2009-01-15T09:26:02.000+0000
As Maurice described in Bug #3474 there is a problem, when you try tu use Zend_Controller_Route_Regex with $router->addConfig($config, 'routes');
The Zend_Config object is initialized with a XML-file.
Due to the limitation of the xml-config object that only strings are returned.
All the mappings 1 ... are not recognized.
Robert
Posted by Robert Hänsel (r-o-b-e-r-t) on 2009-01-15T09:39:59.000+0000
My fix for this problem:
in File Zend/Controller/Router/Route/Regex.php:131
so long
Posted by Robert Hänsel (r-o-b-e-r-t) on 2009-01-15T09:55:13.000+0000
In my last comment was a little Error ...
now it works correct
in File Zend/Controller/Router/Route/Regex.php:131
Posted by David Heidrich (bowlingx) on 2009-08-03T01:55:36.000+0000
Why still not fixed in ZF 1.9.0?
Posted by Robert Hänsel (r-o-b-e-r-t) on 2009-08-18T00:41:01.000+0000
My Solution for this:
Replace Zend/Config/Xml.php (L252-282) with this one:
// Search for children if (count($xmlObject->children()) > 0) { foreach ($xmlObject->children() as $key => $value) { if (count($value->children()) > 0 || count($value->children(self::XML_NAMESPACE)) > 0) { $value = $this->_toArray($value); } else if (count($value->attributes()) > 0 || count($value->attributes(self::XML_NAMESPACE)) > 0) { $attributes = $value->attributes(); $attributesNS = $value->attributes(self::XML_NAMESPACE); // Old Zend_Config Style if (!isset($attributes['value']) && isset($attributes['type'])) { $value = $this->typeConvert($value, $attributes); } elseif (isset($attributes['value'])&& isset($attributes['type'])) { $value = $this->typeConvert($attributes['value'], $attributes); // New Zend_Config Style (1.9+) } elseif (!isset($attributesNS['value']) && isset($attributesNS['type'])) { $value = $this->typeConvert($value, $attributesNS); } elseif (isset($attributesNS['value']) && isset($attributesNS['type'])) { $value = $this->typeConvert($attributesNS['value'], $attributesNS); } elseif (isset($attributes['value'])) { $value = (string) $attributes['value']; } else { $value = $this->_toArray($value); } } else { $value = $this->typeConvert($value, $value->attributes()); } if (array_key_exists($key, $config)) { if (!is_array($config[$key]) || !array_key_exists(0, $config[$key])) { $config[$key] = array($config[$key]); } $config[$key][] = $value; } else { $config[$key] = $value; } } } else if (!isset($xmlObject['extends']) && !isset($nsAttributes['extends']) && (count($config) === 0)) { // Object has no children nor attributes and doesn't use the extends // attribute: it's a string $config = (string) $xmlObject; }And add the following new protected function:
/** * Cast the type in the given Format * * @param mixed $value * @param mixed $attributes * @return mixed - The converted Type */ protected function typeConvert($value, $attributes = array()) { $value = trim((string) $value); if (count($attributes) && isset($attributes['type'])) { switch (strtolower($attributes['type'])) { case 'int': case 'integer': return (int) $value; case 'bool': case 'boolean': return ($value == 'true')?true:false; case 'float': return (float)$value; default: return (string) $value; } } return $value; }Now you can set the Type in the Config-XML File.
Now you can just simply add the type that you want ...
It's possible to write the value as attribute e.g. or to use 123 .. is both the same
If you use the ZF Namespace use or 123
But dont mix it up wont work
Posted by Eugene (codemaker) on 2009-08-21T02:46:50.000+0000
I'm use default method getVariables in a __construct:
{quote} public function __construct($route, $defaults = array(), $map = array(), $reverse = null) { ... $this->_map = $this->getVariables($this->_map); } {quote}
and all works fine
Posted by Jan Pieper (jpieper) on 2009-09-18T15:44:50.000+0000
Fixed in r18294, see [ZF-7658].
Posted by Dolf Schimmel (Freeaqingme) (freak) on 2009-09-18T15:48:52.000+0000
Assigning issue to ~jpieper as he fixed it.