05
Jun
08

teh pwn config parser

made this class (under beta testing atm) which loads config data from pretty special xmls.. thought zend_config_xml is drunk and stupid

sections can be inherited, you can define attributes and have special attributes to handle the parsing.. some features are not implemented yet..

teh pwnage code:

class Gizmo_Config_Xml {
    public $data;
    private $protectedAttributes = array( "_extends"=>"string","_private"=>"boolean" );

    public function __construct($filename,$section = null){
        if (empty($filename)) {
            throw new Exception('Filename is not set');
        }
        $config = simplexml_load_file($filename);
        if (null === $section)
            foreach ($config as $sectionName => $sectionData){
                $this->$sectionName = $sectionData;
            }
    }

    public function __set($var,$val){
        foreach ($val->attributes() as $k=>$v)
            $this->data[$var]['attributes'][$k]= (string) $v;
        $this->data[$var] = $this->_processSection($val,$var);

    }

    private function _processSection($xmlObj){
        $config = array();
        if(count($xmlObj->children())>0){
            foreach($xmlObj->children() as $k=>$v)
                $config['elements'][$k] = $this->_processSection($v);
        }
        foreach($xmlObj->attributes() as $k=>$v)
            $config['attributes'][$k] = (string) $v;
        if(count($xmlObj->children())==0)
            $config['value'] = (string) $xmlObj;

        return $config;
    }

    private function _toArray($data,$sn){
        if(is_array($data['attributes'])){
            foreach($data['attributes'] as $k=>$v)
                if(array_key_exists($k,$this->protectedAttributes)){
                    try{
                        settype($v, $this->protectedAttributes[$k]);
                    }catch (Exception $e){
                        echo $e->getMessage();
                    }
                    if($k=="_extends") {
                        $ret_data = $this->_arrayMergeRecursive($this->data[$v],$data);
                        unset($ret_data['attributes']['_extends']);
                    }
                    if($k=="_private"){
                        $flag_private = true;
                    }
                }else
                    $ret_data['attributes'][$k] = $v;
        }

        if(is_array($data['elements']))
            foreach($data['elements'] as $k=>$v)
                $ret_data['elements'][$k] = $this->_toArray($v,$k);
        elseif(!isset($ret_data))
            $ret_data = $data;

        if(count($ret_data['elements']))
            unset($ret_data['value']);
        else
            $ret_data['value'] = $data['value'];

        return ($flag_private)?FALSE:$ret_data;
    }

    private function _arrayMergeRecursive($array1, $array2){
        if (is_array($array1) && is_array($array2))
            foreach ($array2 as $key => $value)
                if (isset($array1[$key]))
                    $array1[$key] = $this->_arrayMergeRecursive($array1[$key], $value);
                else
                    $array1[$key] = $value;
        else
            $array1 = $array2;

        return $array1;
    }

    public function toArray(){
        $ret = array();
        foreach($this->data as $k=>$v){
            $a = $this->_toArray($v,$k);
            $a!==false ? $ret[$k] = $a : null;
        }
        return $ret;
    }

}

teh xml example:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <_topo _private="true" type="X1:topo">
        <catId type="long" optional="true"></catId>
        <topoId type="long" optional="true" />
        <netId type="long">0</netId>
    </_topo>

    <_pagi _private="true" type="X2:Pagi" namespace="http://x.com/ws/schema">
        <cnt type="boolean" />
        <pageNum type="positiveinteger">1</pageNum>
        <ipp type="positiveInteger">10</ipp>
    </_pagi>

    <_sort _private="true" type="X3:Sort" namespace="http://x.com/ws/schema">
         <sortBy type="string" enum="viewCount,price,averageRating">enum[0]</sortBy>
         <sortOrder type="string" enum="asc,desc">enum[0]</sortOrder>
    </_sort>

    <getSomeList>
        <xId type="long" optional="true" />
        <topology _extends="_topo" />
        <pagination _extends="_pagi" />
        <sort _extends="_sort" />
        <testParam _extends="_sort">
            <testSubParam type="Qx:test" namespace="y.com">
                <testSubSubParam type="long" />
            </testSubParam>
        </testParam>
    </getSomeList>
</config>

tip: it can be used in some nifty soap actions




November 2009
M T W T F S S
« Jun    
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Months

Recent Entries