Exemplo n.º 1
0
function objectToArray($object)
{
    if (!is_object($object) && !is_array($object)) {
        return $object;
    }
    if (is_object($object)) {
        $object = get_object_publics($object);
    }
    return array_map('objectToArray', $object);
}
 /**
  * serializes PHP values in accordance w/ section 5. Type information is
  * not serialized if $use == 'literal'.
  *
  * @param	mixed	$val	The value to serialize
  * @param	string	$name	The name (local part) of the XML element
  * @param	string	$type	The XML schema type (local part) for the element
  * @param	string	$name_ns	The namespace for the name of the XML element
  * @param	string	$type_ns	The namespace for the type of the element
  * @param	array	$attributes	The attributes to serialize as name=>value pairs
  * @param	string	$use	The WSDL "use" (encoded|literal)
  * @param	boolean	$soapval	Whether this is called from soapval.
  * @return	string	The serialized element, possibly with child elements
  * @access	public
  */
 function serialize_val($val, $name = false, $type = false, $name_ns = false, $type_ns = false, $attributes = false, $use = 'encoded', $soapval = false)
 {
     $this->debug("in serialize_val: name={$name}, type={$type}, name_ns={$name_ns}, type_ns={$type_ns}, use={$use}, soapval={$soapval}");
     $this->appendDebug('value=' . $this->publicDump($val));
     $this->appendDebug('attributes=' . $this->publicDump($attributes));
     if (is_object($val) && get_class($val) == 'soapval' && !$soapval) {
         $this->debug("serialize_val: serialize soapval");
         $xml = $val->serialize($use);
         $this->appendDebug($val->getDebug());
         $val->clearDebug();
         $this->debug("serialize_val of soapval returning {$xml}");
         return $xml;
     }
     // force valid name if necessary
     if (is_numeric($name)) {
         $name = '__numeric_' . $name;
     } elseif (!$name) {
         $name = 'noname';
     }
     // if name has ns, add ns prefix to name
     $xmlns = '';
     if ($name_ns) {
         $prefix = 'nu' . rand(1000, 9999);
         $name = $prefix . ':' . $name;
         $xmlns .= " xmlns:{$prefix}=\"{$name_ns}\"";
     }
     // if type is prefixed, create type prefix
     if ($type_ns != '' && $type_ns == $this->namespaces['xsd']) {
         // need to fix this. shouldn't default to xsd if no ns specified
         // w/o checking against typemap
         $type_prefix = 'xsd';
     } elseif ($type_ns) {
         $type_prefix = 'ns' . rand(1000, 9999);
         $xmlns .= " xmlns:{$type_prefix}=\"{$type_ns}\"";
     }
     // serialize attributes if present
     $atts = '';
     if ($attributes) {
         foreach ($attributes as $k => $v) {
             $atts .= " {$k}=\"" . $this->expandEntities($v) . '"';
         }
     }
     // serialize null value
     if (is_null($val)) {
         $this->debug("serialize_val: serialize null");
         if ($use == 'literal') {
             // TODO: depends on minOccurs
             $xml = "<{$name}{$xmlns}{$atts}/>";
             $this->debug("serialize_val returning {$xml}");
             return $xml;
         } else {
             if (isset($type) && isset($type_prefix)) {
                 $type_str = " xsi:type=\"{$type_prefix}:{$type}\"";
             } else {
                 $type_str = '';
             }
             $xml = "<{$name}{$xmlns}{$type_str}{$atts} xsi:nil=\"true\"/>";
             $this->debug("serialize_val returning {$xml}");
             return $xml;
         }
     }
     // serialize if an xsd built-in primitive type
     if ($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])) {
         $this->debug("serialize_val: serialize xsd built-in primitive type");
         if (is_bool($val)) {
             if ($type == 'boolean') {
                 $val = $val ? 'true' : 'false';
             } elseif (!$val) {
                 $val = 0;
             }
         } else {
             if (is_string($val)) {
                 $val = $this->expandEntities($val);
             }
         }
         if ($use == 'literal') {
             $xml = "<{$name}{$xmlns}{$atts}>{$val}</{$name}>";
             $this->debug("serialize_val returning {$xml}");
             return $xml;
         } else {
             $xml = "<{$name}{$xmlns} xsi:type=\"xsd:{$type}\"{$atts}>{$val}</{$name}>";
             $this->debug("serialize_val returning {$xml}");
             return $xml;
         }
     }
     // detect type and serialize
     $xml = '';
     switch (true) {
         case is_bool($val) || $type == 'boolean':
             $this->debug("serialize_val: serialize boolean");
             if ($type == 'boolean') {
                 $val = $val ? 'true' : 'false';
             } elseif (!$val) {
                 $val = 0;
             }
             if ($use == 'literal') {
                 $xml .= "<{$name}{$xmlns}{$atts}>{$val}</{$name}>";
             } else {
                 $xml .= "<{$name}{$xmlns} xsi:type=\"xsd:boolean\"{$atts}>{$val}</{$name}>";
             }
             break;
         case is_int($val) || is_long($val) || $type == 'int':
             $this->debug("serialize_val: serialize int");
             if ($use == 'literal') {
                 $xml .= "<{$name}{$xmlns}{$atts}>{$val}</{$name}>";
             } else {
                 $xml .= "<{$name}{$xmlns} xsi:type=\"xsd:int\"{$atts}>{$val}</{$name}>";
             }
             break;
         case is_float($val) || is_double($val) || $type == 'float':
             $this->debug("serialize_val: serialize float");
             if ($use == 'literal') {
                 $xml .= "<{$name}{$xmlns}{$atts}>{$val}</{$name}>";
             } else {
                 $xml .= "<{$name}{$xmlns} xsi:type=\"xsd:float\"{$atts}>{$val}</{$name}>";
             }
             break;
         case is_string($val) || $type == 'string':
             $this->debug("serialize_val: serialize string");
             $val = $this->expandEntities($val);
             if ($use == 'literal') {
                 $xml .= "<{$name}{$xmlns}{$atts}>{$val}</{$name}>";
             } else {
                 $xml .= "<{$name}{$xmlns} xsi:type=\"xsd:string\"{$atts}>{$val}</{$name}>";
             }
             break;
         case is_object($val):
             $this->debug("serialize_val: serialize object");
             if (get_class($val) == 'soapval') {
                 $this->debug("serialize_val: serialize soapval object");
                 $pXml = $val->serialize($use);
                 $this->appendDebug($val->getDebug());
                 $val->clearDebug();
             } else {
                 if (!$name) {
                     $name = get_class($val);
                     $this->debug("In serialize_val, used class name {$name} as element name");
                 } else {
                     $this->debug("In serialize_val, do not override name {$name} for element name for class " . get_class($val));
                 }
                 foreach (get_object_publics($val) as $k => $v) {
                     $pXml = isset($pXml) ? $pXml . $this->serialize_val($v, $k, false, false, false, false, $use) : $this->serialize_val($v, $k, false, false, false, false, $use);
                 }
             }
             if (isset($type) && isset($type_prefix)) {
                 $type_str = " xsi:type=\"{$type_prefix}:{$type}\"";
             } else {
                 $type_str = '';
             }
             if ($use == 'literal') {
                 $xml .= "<{$name}{$xmlns}{$atts}>{$pXml}</{$name}>";
             } else {
                 $xml .= "<{$name}{$xmlns}{$type_str}{$atts}>{$pXml}</{$name}>";
             }
             break;
             break;
         case is_array($val) || $type:
             // detect if struct or array
             $valueType = $this->isArraySimpleOrStruct($val);
             if ($valueType == 'arraySimple' || preg_match('/^ArrayOf/', $type)) {
                 $this->debug("serialize_val: serialize array");
                 $i = 0;
                 if (is_array($val) && count($val) > 0) {
                     foreach ($val as $v) {
                         if (is_object($v) && get_class($v) == 'soapval') {
                             $tt_ns = $v->type_ns;
                             $tt = $v->type;
                         } elseif (is_array($v)) {
                             $tt = $this->isArraySimpleOrStruct($v);
                         } else {
                             $tt = gettype($v);
                         }
                         $array_types[$tt] = 1;
                         // TODO: for literal, the name should be $name
                         $xml .= $this->serialize_val($v, 'item', false, false, false, false, $use);
                         ++$i;
                     }
                     if (count($array_types) > 1) {
                         $array_typename = 'xsd:anyType';
                     } elseif (isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
                         if ($tt == 'integer') {
                             $tt = 'int';
                         }
                         $array_typename = 'xsd:' . $tt;
                     } elseif (isset($tt) && $tt == 'arraySimple') {
                         $array_typename = 'SOAP-ENC:Array';
                     } elseif (isset($tt) && $tt == 'arrayStruct') {
                         $array_typename = 'unnamed_struct_use_soapval';
                     } else {
                         // if type is prefixed, create type prefix
                         if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']) {
                             $array_typename = 'xsd:' . $tt;
                         } elseif ($tt_ns) {
                             $tt_prefix = 'ns' . rand(1000, 9999);
                             $array_typename = "{$tt_prefix}:{$tt}";
                             $xmlns .= " xmlns:{$tt_prefix}=\"{$tt_ns}\"";
                         } else {
                             $array_typename = $tt;
                         }
                     }
                     $array_type = $i;
                     if ($use == 'literal') {
                         $type_str = '';
                     } else {
                         if (isset($type) && isset($type_prefix)) {
                             $type_str = " xsi:type=\"{$type_prefix}:{$type}\"";
                         } else {
                             $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"" . $array_typename . "[{$array_type}]\"";
                         }
                     }
                     // empty array
                 } else {
                     if ($use == 'literal') {
                         $type_str = '';
                     } else {
                         if (isset($type) && isset($type_prefix)) {
                             $type_str = " xsi:type=\"{$type_prefix}:{$type}\"";
                         } else {
                             $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
                         }
                     }
                 }
                 // TODO: for array in literal, there is no wrapper here
                 $xml = "<{$name}{$xmlns}{$type_str}{$atts}>" . $xml . "</{$name}>";
             } else {
                 // got a struct
                 $this->debug("serialize_val: serialize struct");
                 if (isset($type) && isset($type_prefix)) {
                     $type_str = " xsi:type=\"{$type_prefix}:{$type}\"";
                 } else {
                     $type_str = '';
                 }
                 if ($use == 'literal') {
                     $xml .= "<{$name}{$xmlns}{$atts}>";
                 } else {
                     $xml .= "<{$name}{$xmlns}{$type_str}{$atts}>";
                 }
                 foreach ($val as $k => $v) {
                     // Apache Map
                     if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
                         $xml .= '<item>';
                         $xml .= $this->serialize_val($k, 'key', false, false, false, false, $use);
                         $xml .= $this->serialize_val($v, 'value', false, false, false, false, $use);
                         $xml .= '</item>';
                     } else {
                         $xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
                     }
                 }
                 $xml .= "</{$name}>";
             }
             break;
         default:
             $this->debug("serialize_val: serialize unknown");
             $xml .= 'not detected, got ' . gettype($val) . ' for ' . $val;
             break;
     }
     $this->debug("serialize_val returning {$xml}");
     return $xml;
 }
Exemplo n.º 3
0
 /**
  * serializes the elements for a complexType
  *
  * @param array $typeDef our internal representation of an XML schema type (or element)
  * @param mixed $value a native PHP value (parameter value)
  * @param string $ns the namespace of the type
  * @param string $uqType the local part of the type
  * @param string $use use for part (encoded|literal)
  * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
  * @return string value serialized as an XML string
  * @access private
  */
 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use = 'encoded', $encodingStyle = false)
 {
     $this->debug("in serializeComplexTypeElements for XML Schema type {$ns}:{$uqType}");
     $xml = '';
     if (isset($typeDef['extensionBase'])) {
         $nsx = $this->getPrefix($typeDef['extensionBase']);
         $uqTypex = $this->getLocalPart($typeDef['extensionBase']);
         if ($this->getNamespaceFromPrefix($nsx)) {
             $nsx = $this->getNamespaceFromPrefix($nsx);
         }
         if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
             $this->debug("serialize elements for extension base {$nsx}:{$uqTypex}");
             $xml .= $this->serializeComplexTypeElements($typeDefx, $value, $nsx, $uqTypex, $use, $encodingStyle);
         } else {
             $this->debug("extension base {$nsx}:{$uqTypex} is not a supported type");
         }
     }
     if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
         $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type {$ns}:{$uqType}");
         if (is_array($value)) {
             $xvalue = $value;
         } elseif (is_object($value)) {
             $xvalue = get_object_publics($value);
         } else {
             $this->debug("value is neither an array nor an object for XML Schema type {$ns}:{$uqType}");
             $xvalue = array();
         }
         // toggle whether all elements are present - ideally should validate against schema
         if (count($typeDef['elements']) != count($xvalue)) {
             $optionals = true;
         }
         foreach ($typeDef['elements'] as $eName => $attrs) {
             if (!isset($xvalue[$eName])) {
                 if (isset($attrs['default'])) {
                     $xvalue[$eName] = $attrs['default'];
                     $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
                 }
             }
             // if user took advantage of a minOccurs=0, then only serialize named parameters
             if (isset($optionals) && !isset($xvalue[$eName]) && (!isset($attrs['nillable']) || $attrs['nillable'] != 'true')) {
                 if (isset($attrs['minOccurs']) && $attrs['minOccurs'] != '0') {
                     $this->debug("apparent error: no value provided for element {$eName} with minOccurs=" . $attrs['minOccurs']);
                 }
                 // do nothing
                 $this->debug("no value provided for complexType element {$eName} and element is not nillable, so serialize nothing");
             } else {
                 // get value
                 if (isset($xvalue[$eName])) {
                     $v = $xvalue[$eName];
                 } else {
                     $v = null;
                 }
                 if (isset($attrs['form'])) {
                     $unqualified = $attrs['form'] == 'unqualified';
                 } else {
                     $unqualified = false;
                 }
                 if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
                     $vv = $v;
                     foreach ($vv as $k => $v) {
                         if (isset($attrs['type']) || isset($attrs['ref'])) {
                             // serialize schema-defined type
                             $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
                         } else {
                             // serialize generic type (can this ever really happen?)
                             $this->debug("calling serialize_val() for {$v}, {$eName}, false, false, false, false, {$use}");
                             $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
                         }
                     }
                 } else {
                     if (is_null($v) && isset($attrs['minOccurs']) && $attrs['minOccurs'] == '0') {
                         // do nothing
                     } elseif (is_null($v) && isset($attrs['nillable']) && $attrs['nillable'] == 'true') {
                         // TODO: serialize a nil correctly, but for now serialize schema-defined type
                         $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
                     } elseif (isset($attrs['type']) || isset($attrs['ref'])) {
                         // serialize schema-defined type
                         $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
                     } else {
                         // serialize generic type (can this ever really happen?)
                         $this->debug("calling serialize_val() for {$v}, {$eName}, false, false, false, false, {$use}");
                         $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
                     }
                 }
             }
         }
     } else {
         $this->debug("no elements to serialize for XML Schema type {$ns}:{$uqType}");
     }
     return $xml;
 }