* @license PHP License * @package WB * @subpackage base */ /** * XML config unserializer * * Unserialitze config string from XML to array * * @version 0.1.2 * @package WB * @subpackage base */ class WBConfig_Unserializer extends WBStdClass { /** * XML Unserializer * @var XML_Unserializer */ private $unser; /** * loader sub class * @var WBConfig_Loader */ private $loader; /** * constructor * * start patI18n */ public function __construct() { WBClass::create('patI18n'); // prepare XML_Userializer WBClass::load('XML_Unserializer'); $params = array( XML_UNSERIALIZER_OPTION_WHITESPACE => XML_UNSERIALIZER_WHITESPACE_KEEP, XML_UNSERIALIZER_OPTION_COMPLEXTYPE => 'array', XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY => 'id', XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE => true, XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY => '_attributes', XML_UNSERIALIZER_OPTION_FORCE_ENUM => array('item') ); $this->unser = new XML_Unserializer($params); } /** * Choose loader * * Tell config class how to load XML-strings of config * * @param string $loader */ public function setLoader($loader = 'File') { $this->loader = WBClass::create('WBConfig_Loader_'. $loader); } /** * unserializer XML string * * @param string $in * @return array * @throws WBException_File */ public function unserialize($in) { $res = $this->unser->unserialize($in, false); if ($res instanceof PEAR_Error) { WBClass::load('WBException_Pear'); throw new WBException_Pear( $res->getMessage(), 2, __CLASS__ ); } $raw = $this->unser->getUnserializedData(); $config = array(); if (empty($raw)) { return $config; } $this->raw2array($raw, $config); return $config; } /** * convert raw array to configuration array * * Recursive function that walks through raw condig data * * @param array $raw input data * @param array $tmp current position in current configuration value * @return bool true on success */ private function raw2Array($raw, &$tmp) { // this is trivial if (is_scalar($raw)) { $tmp = $raw; return true; } foreach ($raw as $key => $value) { if( $key == '_attributes' ) { continue; } // if( $key == 'xinc' ) { $this->xinc( $value, $tmp ); continue; } // simple value if( !is_array( $value ) ) { $tmp[$key] = $value; continue; } // is always an indexed array if( $key == 'item' ) { unset( $raw['item'] ); unset( $tmp['item'] ); for( $i = 0; $i < count( $value ); ++$i ) { $this->translate($value[$i]); if (is_array($value[$i]) && isset($value[$i]['_content'])) { $value[$i] = $value[$i]['_content']; } $this->raw2Array( $value[$i], $tmp[$i] ); } continue; } // sequential arrays if( isset( $value[0] ) ) { $tmp[$key] = array(); for( $i = 0; $i < count( $value ); ++$i ) { $this->translate($value[$i]); if (isset($value[$i]['_content'])) { $value[$i] = $value[$i]['_content']; } $tmp[$key][$i] = array(); $this->raw2Array( $value[$i], $tmp[$key][$i] ); } continue; } $this->parameter($value); $this->cast($value); // manage attributes if( isset( $value['_attributes'] ) ) { // "id" is the key if( isset( $value['_attributes']['id'] ) && isset( $value['_content'] ) ) { $this->translate($value); $tmp[$key] = $value['_content']; continue; } $this->translate($value); if( isset( $value['_content'] ) ) { $value = $value['_content']; } } // recursion $tmp[$key] = array(); $this->raw2Array( $value, $tmp[$key] ); } return true; } /** * translate values markt as such * * check for nls-attributes and use patI18n to translate content * * @param array $value */ private function translate(&$value) { if (!is_array($value)) { return; } // translate if (!isset($value['_attributes']) || !isset($value['_attributes']['nls:translate']) || !$value['_attributes']['nls:translate']) { return; } if (empty($value['_content'])) { return; } if (isset($value['_attributes']['nls:domain'])) { $value['_content'] = patI18n::dgettext($value['_attributes']['nls:domain'], $value['_content']); } else { $value['_content'] = patI18n::gettext($value['_content']); } } /** * Use WBParam to populate XML content * * Listen for attributes: param:get and param:sprintf. * * @param array $value */ private function parameter(&$value) { if (!is_array($value)) { return; } // no attributes if (!isset($value['_attributes']) || empty($value['_attributes'])) { return; } $action = ''; $param = ''; foreach ($value['_attributes'] as $k => $v) { if (0 != strncmp('param:', $k, 6)) { continue; } $action = explode(':', $k, 2); $action = $action[1]; $param = WBParam::get($v); break; } // not found? don't do a thing if (empty($action)) { return; } switch ($action) { case 'sprintf': $value['_content'] = sprintf($value['_content'], $param); break; default: case 'get': $value['_content'] = $param; break; } } /** * Cast Value to specific data types * * @param array $value */ private function cast(&$value) { if (!is_array($value)) { return; } // no attributes if (!isset($value['_attributes']) || empty($value['_attributes'])) { return; } if (!isset($value['_attributes']['cast']) || empty($value['_attributes']['cast'])) { return; } switch (strtolower($value['_attributes']['cast'])) { case 'bool': if ('true' == $value['_content']) { $value['_content'] = 1; } else if ('false' == $value['_content']) { $value['_content'] = 0; } else { $value['_content'] = intval($value['_content']); } if (0 < $value['_content']) { $value['_content'] = true; } else { $value['_content'] = false; } break; case 'int': $value['_content'] = intval($value['_content']); break; case 'float': $value['_content'] = floatval($value['_content']); break; default: break; } } /** * xinc * * Include other files * * @param array $value config file to include * @param array $tmp current position in current configuration value * @return bool true on success */ private function xinc($value, &$tmp) { if (!is_array($value) || !isset($value[0])) { $value = array($value); } $incConfig = WBClass::create('WBConfig'); $incConfig->setLoader($this->loader->getName()); foreach ($value as $v) { if (!is_array($v) || !isset($v['_attributes'])) { $incConfig->load($v); $inc = $incConfig->get(); if (is_array($tmp)) { $inc = array_merge($tmp, $inc); } $tmp = $inc; continue; } if (!isset($v['_attributes']['as'])) { WBClass::load( 'WBException_Config' ); throw new WBException_Config('Attribute "as" expected, but not give', 1, __CLASS__); continue; } $key = $v['_attributes']['as']; $incConfig->load( $v['_content'] ); $tmp[$key] = $incConfig->get(); } return true; } } ?>